Javascript 使用Backbone.js依赖的视图、模型、视图和#x27;从另一个视图呈现函数,侦听事件

Javascript 使用Backbone.js依赖的视图、模型、视图和#x27;从另一个视图呈现函数,侦听事件,javascript,backbone.js,Javascript,Backbone.js,是否可以从一个视图中使用另一个视图,该视图列为第一个视图的依赖项、其模型和渲染功能等,但不列为第一个视图的依赖项,所有这些都是使用require.js和Backbone.js定义的 在我的情况下,所有代码文件都已成功加载,但我无法呈现第二个视图,第一个视图没有要呈现的模板,它只是相应地决定将仅登录应用程序视图或入口视图呈现给用户登录,并通过检查lofinModels“loginp”属性的值true或false进行注册?所以我在思考我可能犯的错误。JS控制台没有错误 第一个视图看起来是这样的:

是否可以从一个视图中使用另一个视图,该视图列为第一个视图的依赖项、其模型和渲染功能等,但不列为第一个视图的依赖项,所有这些都是使用require.js和Backbone.js定义的

在我的情况下,所有代码文件都已成功加载,但我无法呈现第二个视图,第一个视图没有要呈现的模板,它只是相应地决定将仅登录应用程序视图或入口视图呈现给用户登录,并通过检查lofinModels“loginp”属性的值true或false进行注册?所以我在思考我可能犯的错误。JS控制台没有错误

第一个视图看起来是这样的:

    define([
  'jquery',
  'ratchet',
  'underscore',
  'backbone',

  'entrance/entranceview',
  'app/appview',
  ],
  function($, Ratchet, _, Backbone, EntranceView, AppView){
      var MainView = Backbone.View.extend({

          el: $('body'),

          initialize: function(){

              this.entranceView = new EntranceView();
              this.entranceView.loginModel.fetch();
              this.listenTo( this.entranceView.loginModel, 'sync', this.render );
              this.appView = new AppView();

              this.render();
          },
          render: function() {
              if ( this.entranceView.loginModel.get('loginp') == true ) {
                  this.appView.render();

                  this.$el.empty();
                  this.$el
                    .append(this.appView.el);
              }
              else {
                  this.entranceView.render();

                  this.$el.empty();               
                  this.$el
                    .append(this.entranceView.el);
              }
          },
      });

      return MainView;
});
第二种观点:

define([
    'underscore',
    'backbone',

    'entrance/loginmodel',
    'entrance/registermodel',

    'text!entrance/logintemplate.html',
    'text!entrance/registertemplate.html',
    ],
    function(_, Backbone, LoginModel, RegisterModel, LoginTemplate, RegisterTemplate){
        var EntranceView = Backbone.View.extend({
            el: $('body'),
            initialize: function(){
                this.loginModel = new LoginModel();
                this.registerModel = new RegisterModel();

                //this.render();
            },
            render: function() {
                this.$el.empty();
                this.$el.html( this.template_login( this.loginModel.attributes ) );
                return this;
            },

            events: {
                'keydown input' : 'updateform',
                'click #renlogbtn' : 'render_login',
                'click #renregbtn' : 'render_register',
                'click #logbtn' : 'login',
                'click #regbtn' : 'register',
            },

            template_login: _.template( LoginTemplate ),
            template_register: _.template( RegisterTemplate ),

            updateform: function(e){
                var el = e.target;
                var formData = {};
                formData[ el.id ] = $(el).val();
                this.loginModel.set( formData );
                this.registerModel.set( formData );
            },
            render_login: function(e){
                e.preventDefault();
                this.$el.empty();
                this.$el.html( this.template_login( this.loginModel.attributes ) );
                return this;
            },
            render_register: function(e){
                e.preventDefault();
                this.$el.empty();
                this.$el.html( this.template_register( this.registerModel.attributes ) );
                return this;
            },
            login: function(e){
                e.preventDefault();
                //$( el ).val('');
                this.loginModel.save();
                console.log( JSON.stringify( this.loginModel.attributes ) );
            },
            register: function(e) {
                e.preventDefault();
                //$( el ).val('');
                this.registerModel.save();
                console.log( JSON.stringify( this.registerModel.attributes ) );

            },
        });

        return EntranceView;
})
第二个视图的一个模型依赖项是:

define([
    'underscore',
    'backbone',
    ],
    function(_, Backbone) {
        var LoginModel = Backbone.Model.extend({

            urlRoot: '/login',
            defaults: {
                username: null,
            },

            initialize: function(){
                this.fetch();
            },
        });

        return LoginModel;
});

此外,我在子视图的initialise属性中不使用render(),因为当我从父视图创建它们时,它们会呈现自己,这是我不希望看到的。因为我想渲染应该渲染的视图。因此,我应该能够从父视图调用子视图的渲染,并且应该能够侦听子视图模型上的事件,并为它们启动子视图的回调。

我认为您的问题是,在调用fetch之后设置了
sync
事件侦听器,可能根本不会调用它。此外,如果您正在从main访问
LoginModel
,那么创建实例并在该视图上添加依赖项的代码可能更清晰

此外,我不认为将两种不同的观点融合在一起是明智之举。看起来您节省了一些行,但是将来维护/修改代码会更加困难。我会用它们的模型创建不同的
LoginView
RegisterView
。不同的职能/职责,不同的类别

此外,像这样一个本身不渲染任何内容的视图看起来更像一个控制器,或者在主干世界中,更像一个路由器。您基本上是根据服务器查询决定显示哪个视图。假设此页面位于“/home”(或带有散列URL的“#home”),则将该逻辑提取到路由器:

var AppRouter = Backbone.Router.extend({
  routes: {
    "home": "showHome",
    "login": "showLogin",
    "register": "showRegister"
  },
  showHome: function(){
    var loginModel = new LoginModel();
    loginModel.fetch({
      success: function(model){
        if(model.get("loginp")){
          //show you app view for logged in users!
          var appView = new AppView();
          appView.render();
        }
        else {
           //not logged in!
           Backbone.history.navigate("/login", {trigger:true})
        }
      }
    );
  },
  showLogin: function(){
     //display your login view
  },
  showRegister: function(){
     //display your register view
  }
});
当然,如果您的登录和入口视图是完整的页面视图,那么它们应该是“body”


这可能看起来像更多的代码,但保持单一责任原则会有很大帮助。

在您回答之前,我所做的是更改子渲染在渲染中的位置:
render:function(){if(This.enterview.loginModel.get('loginp')==true){This.$el.empty();This.$el.append(this.appView.el);this.appView.render();}else{this.$el.empty();this.$el.append(this.enterview.el);this.enterview.render();},它是有效的。但是我认为你对路由器的评论是控制器,我应该考虑的观点。哇,我忘了格式化成代码了。太可怕了。相信我-在那里:一个视图,一个模板,一个责任。谢谢你的答案。但是我不理解var self=this,loginModel=newloginmodel部分。你有打字错误吗。或者你能简单地解释一下吗?嗨,没有输入错误,我声明了self,但最后没有使用它。可以使用单个
var
;声明两个或多个变量)为了清晰起见,我把它删除了。我会试试这个。现在,我已经准备好了作为我的主路由器模块的代码。