铆钉,Backbone.View和Backbone.Collection [英] Rivets, Backbone.View and Backbone.Collection

查看:135
本文介绍了铆钉,Backbone.View和Backbone.Collection的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在过去的几个星期认为我尝试过很多办法让铆钉Backbone.View和Backbone.Collection工作。我所有的尝试,其中通过实例覆盖我已经在互联网上找到。但尽管如此,我没有成功。

下面是我目前正在努力实现的挑战:


  • 制作铆钉承认Backbone.Collection(S),并让所有的事件观察

  • 使用铆钉一个Backbone.View为模板,持有在Backbone.Collection
  • 所有对象输入字段
  • 使用所有这样做的。 - 通过重写铆钉功能就像很多过网的例子所示铆钉的适配器

我的适配器电源$ C ​​$ C是这样的:

  VAR dotAdapter = rivets.adapters [
        。],
        originalSubscribe =
            dotAdapter.subscribe,
        originalUnsubscribe =
            dotAdapter.unsubscribe;    dotAdapter.subscribe =功能(OBJ,的keyPath,回调){
        如果(OBJ ===未定义|| OBJ === NULL){
            返回;
        }      //订阅模式
      如果(OBJ的instanceof Backbone.Collection){                obj.on(添加删除复位',函数(){
                        回调(OBJ);
                    });                obj.on('的变化:+的keyPath,功能(
                        M,V){
                        回调(五);
                    });        }否则如果(OBJ =空&安培;!&放大器; OBJ的instanceof Backbone.Model){            obj.on('的变化:+的keyPath,功能(
                    M,V){
                    回调(五);
                });            obj.on('复位:'+
                    的keyPath,功能(
                        M,V){
                        回调(五);
                    });
        }其他{
            originalSubscribe.apply(
                这一点,参数);
        }
    };    dotAdapter.unsubscribe =
        功能(OBJ,的keyPath,回调){
            如果(OBJ ===未定义|| OBJ === NULL){
                返回;
            }           //退订模型
           如果(OBJ的instanceof Backbone.Collection){
                obj.off(添加删除复位',函数(){
                        回电话(
                                OBJ);
                    });                obj.off('的变化:+的keyPath,功能(M,V){
                    回调(五);
                });            }
            否则,如果(OBJ的instanceof Backbone.Model){
                obj.off('的变化:+的keyPath,功能(M,V){
                        回调(五);
                    });
                obj.off('复位:'+的keyPath,功能(M,V){
                            调试器;
                            回调(五);
                        });
            }其他{
                originalUnsubscribe.apply(
                    这一点,参数);
            }
    };    dotAdapter.read =功能(OBJ,的keyPath){
        如果(OBJ ===空|| OBJ ===未定义){
            返回;
        }        如果(OBJ的instanceof Backbone.Model){
            返回obj.get(的keyPath);
        }
        否则,如果(OBJ的instanceof Backbone.Collection)
        {
            返回obj.models;
        }其他{
            返回OBJ [的keyPath]
        }    };    dotAdapter.publish =功能(OBJ,的keyPath,价值){
        如果(价值===){
            值= NULL;
        }        如果(OBJ的instanceof Backbone.Collection){
            obj.models =价值;
        }
        否则,如果(OBJ的instanceof Backbone.Model){
            obj.set(的keyPath,值);
        }
        其他{
            OBJ [的keyPath] =价值;
        }
    };

任何人都可以点我在正确的方向我怎么也得重写。? - 对于铆钉使其与Backbone.Collection对象工作的适配器

在我的收藏,我将有哪些应在根据模板显示Backbone.Model对象。


解决方案

我强烈建议不要覆盖默认适配器。

这可能会导致在我工作过的人的一个项目意外的行为,例如重写 适配器是这样的:

 得到:函数(OBJ,的keyPath){
 如果(OBJ的instanceof Backbone.Model)
    返回obj.get(的keyPath);
 返回OBJ [的keyPath]
},

这导致了不能够访问其他开发商的直接的模型(财产的之外属性属性 的),造成一些莫名其妙的错误。

对于这样的原因,它是最好创建特殊用途的情况下单独的适配器。此外,他们更容易被看到与嵌套结构打交道时,这是非常有用的绑定了解对象之间的关系。

有关例如:网​​友:roles.admin:// priviledges.create见状我们弄清楚用户和管理员都是模型

下面是使用一个简单的例子展示rivets.js文档中

由于通过在JavaScript引用传递对象,更新车型将自动反映在收集,无需担心使铆钉观察骨干收集事件

\r
\r

rivets.adapters [':'] = {\r
  观察:函数(OBJ,的keyPath,回调){\r
    obj.on('的变化:+的keyPath,回调)\r
  },\r
  unobserve:函数(OBJ,的keyPath,回调){\r
    obj.off('的变化:+的keyPath,回调)\r
  },\r
  得到:函数(OBJ,的keyPath){\r
    返回obj.get(的keyPath)\r
  },\r
  设置:功能(OBJ,的keyPath,价值){\r
    obj.set(的keyPath,值)\r
  }\r
}\r
VAR数据= [{\r
  名称:约翰,\r
  年龄:10\r
},{\r
  名称:约瑟夫\r
  年龄:11\r
},{\r
  名称:欢乐,\r
  年龄:12\r
}]\r
\r
变种userCollection =新Backbone.Collection(数据);\r
VAR查看= Backbone.View.extend({\r
  初始化:功能(选件){\r
    this.render()\r
  },\r
  渲染:功能(){\r
    rivets.bind(this.el,{\r
      用户:this.collection\r
    });\r
  }\r
});\r
VAR userView =新景({\r
  EL:'#用户名单,\r
  集合:userCollection\r
});

\r

&LT;脚本SRC =htt​​ps://ajax.googleapis.com/ajax /libs/jquery/2.1.1/jquery.min.js\"></script>\r
&LT;脚本src=\"https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js\"></script>\r
&所述; SCRIPT SRC =htt​​ps://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.2.3/backbone-min.js&GT;&下; /脚本&GT;\r
&所述; SCRIPT SRC =htt​​ps://cdnjs.cloudflare.com/ajax/libs/rivets/0.8.1/rivets.bundled.min.js&GT;&下; /脚本&GT;\r
&LT; UL ID ='用户列表'&GT;\r
  &LT;李RV-每个用户=users.models&GT;\r
    &LT;输入类型=文本RV值=用户:年龄/&GT;\r
    &LT;跨度&GT; {用户:名}&LT; / SPAN&GT;&LT;跨度&GT; {用户:年龄}&LT; / SPAN&GT;\r
  &LT; /李&GT;\r
&LT; / UL&GT;

\r

\r
\r

In the last view weeks I tried many ways to get Rivets work with Backbone.View and Backbone.Collection. All my tries where covered by examples I have found on the internet. But still, I'm not successful.

Here is the challenge I currently try to realize:

  • Making Rivets recognize Backbone.Collection(s) and getting all events observed
  • Use a Backbone.View as template for Rivets which holds input fields for all objects in the Backbone.Collection
  • Using all for this the "."-adapter of Rivets by overriding the Rivets function like shown in a lot of examples over the net.

My adapter source code looks like this:

    var dotAdapter = rivets.adapters[
        '.'],
        originalSubscribe =
            dotAdapter.subscribe,
        originalUnsubscribe =
            dotAdapter.unsubscribe;

    dotAdapter.subscribe = function (obj, keypath, callback) {          
        if (obj === undefined || obj === null) {
            return;
        }

      // Subscribe model
      if (obj instanceof Backbone.Collection) {

                obj.on('add remove reset', function () {
                        callback(obj);
                    });

                obj.on('change:' + keypath, function (
                        m, v) {
                        callback(v);
                    });

        } else if (obj != null && obj instanceof Backbone.Model) {

            obj.on('change:' + keypath, function (
                    m, v) {
                    callback(v);
                });

            obj.on('reset:' +
                    keypath, function (
                        m, v) {
                        callback(v);
                    });
        } else {
            originalSubscribe.apply(
                this, arguments);
        }
    };

    dotAdapter.unsubscribe =
        function (obj, keypath,callback) {
            if (obj === undefined || obj === null ) {
                return;
            }

           // Unsubscribe model
           if (obj instanceof Backbone.Collection) {
                obj.off('add remove reset', function () {
                        callback(
                                obj);
                    });

                obj.off('change:' + keypath, function (m, v) {
                    callback(v);
                });

            }
            else if (obj instanceof Backbone.Model) {
                obj.off('change:' + keypath, function (m, v) {
                        callback(v);
                    });
                obj.off('reset:' + keypath, function (m, v) {
                            debugger;
                            callback(v);
                        });
            } else {
                originalUnsubscribe.apply(
                    this, arguments);
            }
    };

    dotAdapter.read = function (obj,keypath) {
        if (obj === null || obj === undefined ) {
            return;
        }

        if (obj instanceof Backbone.Model) {
            return obj.get(keypath);
        }
        else if (obj instanceof Backbone.Collection)
        {
            return obj.models;
        } else {
            return obj[keypath];
        }

    };

    dotAdapter.publish =  function (obj, keypath, value) {
        if (value === "") {
            value = null;
        }

        if (obj instanceof Backbone.Collection) {
            obj.models = value;
        }
        else if (obj instanceof Backbone.Model) {
            obj.set(keypath, value);
        }
        else {
            obj[keypath] = value;
        }
    };

Can anyone point me in the right direction how I have to override the "."-adapter of rivets for making it work with Backbone.Collection object?

In my collections I will have Backbone.Model objects which should be shown on the according template.

解决方案

I strongly suggest not to override the default . adapter.

This can cause unexpected behaviour, for example in one of the projects I have worked someone overridden the . adapter to something like this:

get: function(obj, keypath) {
 if(obj instanceof Backbone.Model)
    return obj.get(keypath);
 return obj[keypath];
},

this resulted in other developers not being able to access a direct property in the model (properties outside attributes) which caused few weird bugs.

For such reasons, it's better to create separate adapters for special use cases. Also they make it easier to understand the relationship between objects by seeing the bindings which is very useful when dealing with nested structures.

For eg: users:roles.admin:priviledges.create // seeing this we figure out that users and admin are both models

Below is a simple example using the : showcased in rivets.js documentation.

Since objects are passed via reference in javascript, updates to models will automatically reflect in collection, no need to worry about making rivets observe backbone collection events

rivets.adapters[':'] = {
  observe: function(obj, keypath, callback) {
    obj.on('change:' + keypath, callback)
  },
  unobserve: function(obj, keypath, callback) {
    obj.off('change:' + keypath, callback)
  },
  get: function(obj, keypath) {
    return obj.get(keypath)
  },
  set: function(obj, keypath, value) {
    obj.set(keypath, value)
  }
}
var data = [{
  name: "john",
  age: 10
}, {
  name: "joseph",
  age: 11
}, {
  name: "joy",
  age: 12
}]

var userCollection = new Backbone.Collection(data);
var View = Backbone.View.extend({
  initialize: function(options) {
    this.render()
  },
  render: function() {
    rivets.bind(this.el, {
      users: this.collection
    });
  }
});
var userView = new View({
  el: '#user-list',
  collection: userCollection
});

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.2.3/backbone-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/rivets/0.8.1/rivets.bundled.min.js"></script>
<ul id='user-list'>
  <li rv-each-user="users.models">
    <input type="text" rv-value="user:age"/>
    <span>{user:name}</span><span> {user:age}</span>
  </li>
</ul>

这篇关于铆钉,Backbone.View和Backbone.Collection的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆