铆钉,Backbone.View和Backbone.Collection

时间:2014-03-23 15:26:30

标签: backbone.js rivets.js

在上周的视图中,我尝试了很多方法让Rivets使用Backbone.View和Backbone.Collection。我在互联网上找到的例子所涵盖的所有尝试。但是,我还没有成功。

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

  • 让铆钉识别Backbone.Collection并观察所有事件
  • 使用Backbone.View作为Rivets的模板,其中包含Backbone.Collection中所有对象的输入字段
  • 通过覆盖铆钉功能,通过网络上的大量示例所示,使用All来实现铆钉的"。" -adapter。

我的适配器源代码如下所示:

    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;
        }
    };

任何人都可以指出我正确的方向如何覆盖"。" -adapter of rivets以使其与Backbone.Collection对象一起使用?

在我的馆藏中,我将使用Backbone.Model对象,这些对象应该显示在相应的模板上。

2 个答案:

答案 0 :(得分:2)

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

这可能会导致意外行为,例如在我曾经工作的某个项目中,有人将.适配器覆盖为这样的内容:

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

这导致其他开发人员无法访问模型中的 direct 属性(属性attributes 之外的属性),这导致了一些奇怪的错误。

出于这些原因,为特殊用例创建单独的适配器会更好。通过查看在处理嵌套结构时非常有用的绑定,它们还可以更容易地理解对象之间的关系。

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

以下是使用rivets.js文档中展示的:的简单示例。

由于对象是通过javascript中的引用传递的,因此对模型的更新将自动反映在集合中,无需担心使铆钉观察骨干集合事件



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>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

我是铆钉的新手。所以我在寻找适配器并尝试了你的代码。它对我有用。所以我发布这个,所以它可以帮助像我这样的人..

我的html页面包含以下内容:&#39;:&#39;适配器。

<ul id='item-list'>
<li rv-each-contact="contacts:">
  <a  rv-href='contact:url' >{contact:Name}</a></br></br>
  </li>

</ul>

使代码适用于&#39;。&#39;适配器,我改变了行

<li rv-each-contact="contacts:">

 <li rv-each-contact="contacts.">