Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.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
backbone.js视图在获取模型之前渲染_Backbone.js - Fatal编程技术网

backbone.js视图在获取模型之前渲染

backbone.js视图在获取模型之前渲染,backbone.js,Backbone.js,我正在尝试制作一个小型的backbone.js应用程序,但却在与事情的顺序作斗争 在我的html文件中,标题中有两个脚本块: <script type="text/template" id="model-template"> <a href="#"><%= title %></a> </script> <script type="text/javascript"> jQuery(function(){ wi

我正在尝试制作一个小型的backbone.js应用程序,但却在与事情的顺序作斗争

在我的html文件中,标题中有两个脚本块:

<script type="text/template" id="model-template">
  <a href="#"><%= title %></a>
</script>

<script type="text/javascript">
  jQuery(function(){
    window.model.fetch();
  }); 
</script>
该应用程序由一个简单的sinatra应用程序提供服务。url
/mymodel
提供一个静态json文件:

{
    "title": "My Model",
}
加载应用程序时,javascript控制台中出现错误:

Uncaught ReferenceError: title is not defined
问题似乎是,视图在从服务器获取模型之前呈现自身。为什么会这样?

昨天,我关注了PeepCode的前两个backbone.js屏幕广播。我试着将我的应用程序与来自屏幕广播的应用程序进行比较,但看不出我的应用程序需要工作的原因


有什么建议吗

您始终可以使用“默认”选项设置默认标题:

从服务器重置模型的状态。如果模型具有 从未填充过数据,或者如果您希望确保 具有最新的服务器状态。如果发生以下情况,将触发“更改”事件: 服务器的状态与当前属性不同。接受 选项散列中的成功和错误回调,已传递 (模型、响应)作为参数

在本例中,您将希望在成功回调中呈现视图

model.fetch({
   error: function () {
   },
   success: function (model, response) { // model is ready now
      // do view stuff here
   }
});

在这种情况下,您应该引导您的模型数据,以便它在页面加载时可用

而不是

window.model.fetch();
将类似的内容放入(如果使用.erb)

或者处理模型的成功。获取并渲染视图

window.model.fetch({
   success: function (model, response) { 
      window.MyApp.myModelView.render();
   }
});

显然,从前面的回答中,您知道需要在fetchsuccess回调上进行渲染,但是我认为您的问题远不止这些。也就是说,主路径用于立即构建myModelView,而不是在其数据加载时。之所以发生这种情况,是因为您正在调用render()以便将其附加到正文中。相反,请尝试使用现有元素初始化视图。通过这种方式,您可以延迟对render的调用,直到fetch完成:

window.MyApp = Backbone.Router.extend({
    routes: {
        '': 'home'
    },

    initialize: function () {

    },

    home: function() {
        var $body = $(document.body).empty();
        var myModelEl = $("<div></div>").appendTo($body);

        this.myModelView = new MyModelView({
            model: window.mymodel,
            el: myModelEl
        });
    }
 });
window.MyApp=Backbone.Router.extend({
路线:{
“家”
},
初始化:函数(){
},
主页:函数(){
var$body=$(document.body).empty();
var mymodel=$(“”)。appendTo($body);
this.myModelView=新建myModelView({
型号:window.mymodel,
我的模特儿
});
}
});

现在,您还没有调用render(),但您的视图已按预期成功连接到DOM。

您还可以利用Backbone.Model.fetch()返回的延迟对象,如下所示:

window.MyModel = Backbone.Model.extend({
   url: '/mymodel'
});

//when the model is fetched, store a reference to the jQuery deferred object
window.MyModelFetch = window.MyModel.fetch();

window.MyModelView = Backbone.View.extend({
    template: _.template($('#mymodel-template').html()), 

    initialize: function () {
        _.bindAll(this, 'render');
    },

    render: function () {
        //reference the deferred object and use 'done' method 
        //to register a callback after complete
        window.MyModelFetch.done(function(){
             var renderedContent = this.template(this.model.toJSON());
             $(this.el).html(renderedContent);
             return this;
        }
    }
});
 Backbone.DeferrableModel = Backbone.Model.extend({
      fetch: function(){
           this.fetching = Backbone.Model.prototype.fetch.apply(this, arguments);
           return this.fetching;
      }
 });
您可能希望创建主干模型的扩展,该扩展将延迟对象存储在您可以引用的模型上,如下所示:

window.MyModel = Backbone.Model.extend({
   url: '/mymodel'
});

//when the model is fetched, store a reference to the jQuery deferred object
window.MyModelFetch = window.MyModel.fetch();

window.MyModelView = Backbone.View.extend({
    template: _.template($('#mymodel-template').html()), 

    initialize: function () {
        _.bindAll(this, 'render');
    },

    render: function () {
        //reference the deferred object and use 'done' method 
        //to register a callback after complete
        window.MyModelFetch.done(function(){
             var renderedContent = this.template(this.model.toJSON());
             $(this.el).html(renderedContent);
             return this;
        }
    }
});
 Backbone.DeferrableModel = Backbone.Model.extend({
      fetch: function(){
           this.fetching = Backbone.Model.prototype.fetch.apply(this, arguments);
           return this.fetching;
      }
 });
然后在视图渲染方法中,可以这样说:

  render: function () {
        //the deferred reference is now directly referenced from your model
        this.model.fetching.done(function(){
             var renderedContent = this.template(this.model.toJSON());
             $(this.el).html(renderedContent);
             return this;
        }
    }    

使用扩展模型并在整个主干应用程序中遵循此模式非常方便。

True,但随后使用错误数据渲染视图:PSo在这里,您正在initialize和home函数中创建MyModelView的实例?或者我应该将其从初始化中删除?如果正确,请将其从初始化中删除。很抱歉给你带来了困惑。不管怎样,把它放在初始化中并不总是有意义的,因为根据调用的路由方法,通常会呈现不同的视图。我删除了在路由器中呈现的调用,但保留了将视图“el”属性添加到文档中的代码。因此,当获取完成时,它会更改我的模型,从而引发更改事件,调用render方法。。。我花了几个小时才弄明白这就是为什么我的应用程序不能正常工作,有时不能正常工作,或者只能在某些浏览器上工作,而不能在其他浏览器上工作。我想,当你考虑fetch应该如何工作时,这是一个新手的错误。吸取的教训。我认为有太多的主干网示例使用了硬编码数据和非常重要的概念,比如这个被搁置一旁的概念。
  render: function () {
        //the deferred reference is now directly referenced from your model
        this.model.fetching.done(function(){
             var renderedContent = this.template(this.model.toJSON());
             $(this.el).html(renderedContent);
             return this;
        }
    }