如何在 backbone 中实现 angular 样式指令?

How to implement angular style directives in backbone?

我知道这个图书馆 https://github.com/berzniz/backbone.directives。但是我想知道是否有一种方法可以在不使用库的情况下在 backbone 中实现 angular 样式指令。(可能通过下划线或 backbone 视图)我的用例是我想要仅当变量 isVisible 为真时,div 标记内的 html 才可见。

<div bb-show="isVisible">
   <h1>You can see this</h1>
</div>

有没有办法通过backbone实现这个?

在Angular中你有独特的双向数据绑定概念:

.controller("myCtrl", function($scope) {
    $scope.isVisible = true;
    $scope.hide = function() {
        this.isVisible = false;
    }
})

视图可以访问模型,在视图中显示模型数据有几种方式,其中一种是使用ng-show指令:

ng-show="isVisible"

AngularJS example

Backbone.js 不做任何数据绑定。但是你可以使用 underscore template 方法并传入一个数据对象,该对象具有与模板的自由变量对应的属性。:

this.$el.html(this.template({
    isVisible: this.condition
}));

现在您的 isVisible 变量在您的模板中可用。如果它是假的,它不会呈现 HTML,否则它会。

<script id="myTemplate" type="text/template" >
    <% if(isVisible) { %>
    <div>
       <h1>You can see this</h1>
    </div>
    <% } %>
    <button class="js-hide">Hide</button>
</script>

BackboneJS example

没有图书馆,很难实现。我发现 stick.it 对两种方式的绑定有帮助:https://github.com/NYTimes/backbone.stickit

来自他们的文档:

"Similar to view.events, you can define view.bindings to map selectors to binding configurations. The following bindings configuration will bind the view.$('#title') element to the title model attribute and the view.$('#author') element to the authorName model attribute:"

bindings: {
  '#title': 'title',
  '#author': 'authorName'
}

如果您只想根据变量值隐藏渲染部分,请查看 t_dom93 的 关于 Underscore 模板。


Backbone 不是一个框架,它是一个工具箱。它不进行绑定,甚至不自己进行渲染。默认情况下,它使用 jQuery 并让您根据自己的喜好实现绑定。因此,像 angular 一样在没有库的情况下实现 two-way 绑定需要等同于编写自己的库,使用 jQuery 在 HTML 标签上使用自定义 data 属性绑定数据.


Epoxy.js

我发现最接近的是 Epoxy.js。它提供 two-way 像 Stickit 一样的绑定,但也提供过滤器、处理程序、计算字段。

很容易集成到现有项目中。它几乎是透明的,如果你开始使用它,你 没有义务 在任何地方使用它,因为香草 Backbone 和 Epoxy 都可以 co-exist.

绑定示例

ng-show 行为可以通过 toggle handler(one-way 绑定)实现:

<div data-bind="toggle:modelAttribute">
    This is visible only if modelAttribute is truthy.
</div>

ng-modelvalue handler(two-way 绑定)并且可以与任何其他处理程序组合:

<input name="firstname" data-bind="value:firstname,events:['keydown']">

参见 all the handlers

计算属性

An Epoxy model introduces computed attributes, which operate as accessors and mutators. A computed attribute will get an assembled value derived from other model attributes, and will set one more more mutated values back to the model. Computed attributes may be get and set just like normal model attributes, and will trigger "change" events on the model when modified, however they do not exist within the model's attributes table, nor will they be saved with model data.

var BindingModel = Backbone.Epoxy.Model.extend({
  defaults: {
    firstName: "Obi-Wan",
    lastName: "Kenobi"
  },
  computeds: {
    fullName: function() {
        return this.get("firstName") +" "+ this.get("lastName");
    }
  }
});

var view = new Backbone.Epoxy.View({
  el: "#app-computed",
  model: new BindingModel()
});

在模板中

<div id="app-computed">
  <label>First:</label>
  <input type="text" data-bind="value:firstName,events:['keyup']">

  <label>Last:</label>
  <input type="text" data-bind="value:lastName,events:['keyup']">

  <b>Full Name:</b>
  <span data-bind="text:fullName"></span>
</div>

绑定过滤器

Epoxy tries to strike a balance between robust binding options and clean binding definitions. While Epoxy uses a similar binding technique to Knockout.js, it intentionally discourages some of Knockout's inline-javascript allowances.

Instead, Epoxy provides filtering wrappers for formatting data directly within your bindings. Notice how the not() and format() filters are used in the following binding scheme:

<span data-bind="toggle:not(firstName)">Please enter a first name.</span>

参见 all the filters


Knockback.js

如果您已经喜欢 Knockout.js 并且缺少 Backbone 的某些功能,那么 Knockback.js 可能是最好的选择。他们在 CoffeeScript 和 JS 中提供了相当完整的文档。

ViewModel 和 Observable

与 Epoxy 相比,这是一个额外的步骤,后者将模型与绑定和计算完全分开。

var model = new Backbone.Model({first_name: "Planet", last_name: "Earth"});

var ViewModel = function(model) {
  this.first_name = kb.observable(model, 'first_name');
  this.last_name = kb.observable(model, 'last_name');
  this.full_name = ko.computed((function() {return "" + (this.first_name()) + " " + (this.last_name());}), this);
};

var view_model = new ViewModel(model);

ko.applyBindings(view_model, $('#kb_observable')[0]);

模板绑定真的很像:

<input data-bind="value: first_name, valueUpdate: 'keyup'" />