Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Backbone.js,无法在回调上设置上下文_Javascript_Backbone.js_Marionette - Fatal编程技术网

Javascript Backbone.js,无法在回调上设置上下文

Javascript Backbone.js,无法在回调上设置上下文,javascript,backbone.js,marionette,Javascript,Backbone.js,Marionette,好的,我正在研究一个方法来覆盖模型上的fetch方法。我希望能够向它传递一个URL列表,并让它对每个URL进行提取,对结果应用一些处理,然后在它们全部完成后更新自己的属性。以下是基本设计: 一个名为AllVinces的父“包装器”模型有一个自定义的获取函数,该函数在实例化时读取给定的URL列表 对于每个URL,它创建一个子模型,并在其上调用fetch,指定该URL以及一个成功回调 AllVinces实例还有一个属性progress,它需要在成功回调中更新该属性,以便它知道所有子获取何时完成 这就

好的,我正在研究一个方法来覆盖模型上的fetch方法。我希望能够向它传递一个URL列表,并让它对每个URL进行提取,对结果应用一些处理,然后在它们全部完成后更新自己的属性。以下是基本设计:

  • 一个名为AllVinces的父“包装器”模型有一个自定义的获取函数,该函数在实例化时读取给定的URL列表
  • 对于每个URL,它创建一个子模型,并在其上调用fetch,指定该URL以及一个成功回调
  • AllVinces实例还有一个属性progress,它需要在成功回调中更新该属性,以便它知道所有子获取何时完成
  • 这就是我遇到的问题。当子模型获取完成时,成功回调没有最初调用它的父模型的上下文。我对它进行了黑客攻击,因为我可以访问该模块并将父模型存储在一个变量中,但这对我来说似乎不正确。父模型执行子模型的fetch,因此它应该能够以某种方式传递上下文。我不想在那里硬编码引用

    TL;博士

    下面是我的JSFIDLE,它说明了这个问题。有趣的部分从第13行开始

    完整代码:

    // Define the app and a region to show content
    // -------------------------------------------
    var App = new Marionette.Application();
    App.addRegions({
        "mainRegion": "#main"
    });
    
    App.module("SampleModule", function (Mod, App, Backbone, Marionette, $, _) {
        var MainView = Marionette.ItemView.extend({
            template: "#sample-template"
        });
    
        var AllVenues = Backbone.Model.extend({
            progress: 0,
            join: function (model) {
                this.progress++;
                // do some processing of each model
                if (this.progress === this.urls.length) this.finish();
            },
            finish: function() {
                // do something when all models have completed
                this.progress = 0;
                console.log("FINISHED!");
            },
            fetch: function() {
                successCallback = function(model) {
                    console.log("Returning from the fetch for a model");
                    Mod.controller.model.join(model);
                };
                _.bind(successCallback, this);
                $.each(this.urls, function(key, val) {
                    var venue = new Backbone.Model();
                    venue.url = val;
                    venue.fetch({
                        success: successCallback
                    });
                });
            }
        }); 
    
        var Venue = Backbone.Model.extend({
            toJSON: function () {
                return _.clone(this.attributes.response);
            }
        });
    
        var Controller = Marionette.Controller.extend({
            initialize: function (options) {
                this.region = options.region;
                this.model = options.model;
                this.listenTo(this.model, 'change', this.renderRegion);
            },
            show: function () {
                this.model.fetch();
            },
            renderRegion: function () {
                var view = new MainView({
                    model: this.model
                });
                this.region.show(view);
            }
        });
        Mod.addInitializer(function () {
            var allVenues = new AllVenues();
            allVenues.urls = [
                'https://api.foursquare.com/v2/venues/4a27485af964a52071911fe3?oauth_token=EWTYUCTSZDBOVTYZQ3Z01E54HMDYEPZMWOC0AKLVFRBIEXV4&v=20130811',
                'https://api.foursquare.com/v2/venues/4afc4d3bf964a520512122e3?oauth_token=EWTYUCTSZDBOVTYZQ3Z01E54HMDYEPZMWOC0AKLVFRBIEXV4&v=20130811',
                'https://api.foursquare.com/v2/venues/49cfde17f964a520d85a1fe3?oauth_token=EWTYUCTSZDBOVTYZQ3Z01E54HMDYEPZMWOC0AKLVFRBIEXV4&v=20130811'
            ];
            Mod.controller = new Controller({
                region: App.mainRegion,
                model: allVenues
            });
            Mod.controller.show();
        });
    });
    App.start();
    

    我想你误解了工作原理<代码>.\uz.bind返回绑定函数,它不会就地修改它。事实上,在这方面,文档可能会更清晰一些

    因此:

    _.bind(successCallback, this);
    
    没有意义,因为您忽略了
    返回的绑定函数。我想你应该这样说:

    var successCallback = _.bind(function(model) {
        console.log("Returning from the fetch for a model");
        Mod.controller.model.join(model);
    }, this);
    

    还请注意,我添加了一个缺少的
    var
    ,可能您不希望
    successCallback
    是全局的。

    谢谢,这真的很有帮助。我想我被语法弄糊涂了,因为它的兄弟方法bindAll()没有分配给任何对象。您遗漏的一点是实际上下文本身,它在函数之后传入。我在每个模型上用一些hokey处理更新了fiddle,只是为了测试它是否工作。它是!感谢您对缺少的
    参数的提示。调用
    .bindAll(obj,…)
    时,在第一个参数中传递一个
    this
    ,以便下划线可以用绑定函数替换
    obj
    中的属性。如果你看一下,你会发现
    .bindAll
    只不过是一个
    obj[f]=\uj.bind(obj[f],obj)
    循环。@TNguyen:这个答案可能很有趣:。