KnockoutJS 3.X API 第四章 数据绑定(4) 控制流with绑定

if绑定目的

with绑定的目的

foreach绑定

一个例子

with绑定的目的

使用with绑定的格式为data-bind=”with:attribute”,使用with绑定会将其后所跟的属性看作一个新的上下文进行绑定。with绑定内部的所有元素将受到该上下文的约束。

当然,with绑定也可配合if或foreach绑定一起使用。

澳门威尼斯人赌场,if绑定一般是格式是data-bind=if:attribute,if后所跟属性或表达式的值应为bool值(也可以是非bool值,当非空字符串时则为真),if绑定的作用与visible绑定的作用类似。可控制DOM的显示与隐藏,不一样的地方是,if绑定是物理删除或添加DOM元素。

使用with绑定的格式为data-bind=”with:attribute”,使用with绑定会将其后所跟的属性看作一个新的上下文进行绑定。with绑定内部的所有元素将受到该上下文的约束。

foreach绑定主要用于循环展示监控数组属性中的每一个元素,一般用于table标签中

澳门威尼斯人赌场 1

示例1

<h1 data-bind="text: city"> </h1>
<p data-bind="with: coords">
    Latitude:  ,
    Longitude:  
</p>

<script type="text/javascript">
    ko.applyBindings({
        city: "London",
        coords: {
            latitude:  51.5001524,
            longitude: -0.1262362
        }
    });
</script>

本例中,通过with直接绑定了coords监控属性,并在其内部直接调用了coords监控属性的内部属性。这里就体现了with绑定的特性。

示例1

当然,with绑定也可配合if或foreach绑定一起使用。

假设你有一个监控属性数组,每当您添加,删除或重新排序数组项时,绑定将有效地更新UI的DOM-插入或去除相关项目或重新排序现有的DOM元素,不影响任何其他的DOM元素。

UI源码:

示例2:一个互动的例子

Twitter account:   

Get tweets

该例展示IF绑定的动态删除添加DOM:

示例1

当然,也可以配合其他控制流一起适用,例如if和with。

<h4>First instance, without parameters</h4>
<div data-bind='component: "message-editor"'></div>
<h4>Second instance, passing parameters</h4>
<div data-bind='component: {
name: "message-editor",
params: { initialText: "Hello, world!" }
}'></div>

Recent tweets fetched at

Clear tweets

该例子中将使用with绑定动态添加和删除其绑定值为null/undefined或非null/undefined

UI源码:

<form data-bind="submit: getTweets">
    Twitter account:
    <input data-bind="value: twitterName" />
    <button type="submit">Get tweets</button>
</form>

<div data-bind="with: resultData">
    <h3>Recent tweets fetched at  </h3>
    <ol data-bind="foreach: topTweets">
        <li data-bind="text: text"></li>
    </ol>

    <button data-bind="click: $parent.clearResults">Clear tweets</button>
</div>

视图模型源码:

function AppViewModel() {
    var self = this;
    self.twitterName = ko.observable('@example');
    self.resultData = ko.observable(); // No initial value

    self.getTweets = function() {
        var name = self.twitterName(),
            simulatedResults = [
                { text: name + ' What a nice day.' },
                { text: name + ' Building some cool apps.' },
                { text: name + ' Just saw a famous celebrity eating lard. Yum.' }
            ];

        self.resultData({ retrievalDate: new Date(), topTweets: simulatedResults });
    }

    self.clearResults = function() {
        self.resultData(undefined);
    }
}

ko.applyBindings(new AppViewModel());

 

Display message

<h1 data-bind="text: city"> </h1>
<p data-bind="with: coords">
Latitude:  ,
Longitude:  
</p>
<script type="text/javascript">
ko.applyBindings({
city: "London",
coords: {
latitude: 51.5001524,
longitude: -0.1262362
}
});
</script>

示例1:遍历监控属性数组

视图模型源码:

备注:with的无容器绑定(虚拟绑定)

像if、foreach等的虚拟绑定一样,with绑定也一样。使用<!-- ko --><!-- /ko -->进行。

<ul>
    <li>Header element</li>
    <!-- ko with: outboundFlight -->
        ...
    <!-- /ko -->
    <!-- ko with: inboundFlight -->
        ...
    <!-- /ko -->
</ul>

UI源码:

本例中,通过with直接绑定了coords监控属性,并在其内部直接调用了coords监控属性的内部属性。这里就体现了with绑定的特性。

本例适用foreach绑定,在一个table标签中循环显示监控属性数组的内容

ko.components.register('message-editor', {
viewModel: function(params) {
this.text = ko.observable(params && params.initialText || '');
},
template: 'Message: <input data-bind="value: text" /> '
+ '(length: )'
});
ko.applyBindings();
<label><input type="checkbox" data-bind="checked: displayMessage" /> Display message</label>
<div data-bind="if: displayMessage">Here is a message. Astonishing.</div>

示例2:一个互动的例子

<table>
<thead>
<tr><th>First name</th><th>Last name</th></tr>
</thead>
<tbody data-bind="foreach: people">
<tr>
<td data-bind="text: firstName"></td>
<td data-bind="text: lastName"></td>
</tr>
</tbody>
</table>
<script type="text/javascript">
ko.applyBindings({
people: [
{ firstName: 'Bert', lastName: 'Bertington' },
{ firstName: 'Charles', lastName: 'Charlesforth' },
{ firstName: 'Denise', lastName: 'Dentiste' }
]
});
</script>

这只是一个非常简单的例子,在开发中,一般都是将View
Model和Template写成单独外部文件,然后通过ko的components.register方法注册他们,在以后的KO高级应用系列中将会进一步讲解。

视图模型源码:

澳门威尼斯人赌场 2

示例2:添加或删除项目

API

ko.applyBindings({
displayMessage: ko.observable(false)
});

该例子中将使用with绑定动态添加和删除其绑定值为null/undefined或非null/undefined

澳门威尼斯人赌场 3

使用component绑定有两种绑定语法

示例2

UI源码:

UI源码:

1. 快速语法:

该示例中,通过foreach绑定循环planets监控属性数组,其中name为Mercury的项目中capital为null,则循环中该项目只显示其name.

<form data-bind="submit: getTweets">
Twitter account:
<input data-bind="value: twitterName" />
<button type="submit">Get tweets</button>
</form>
<div data-bind="with: resultData">
<h3>Recent tweets fetched at  </h3>
<ol data-bind="foreach: topTweets">
<li data-bind="text: text"></li>
</ol>
<button data-bind="click: $parent.clearResults">Clear tweets</button>
</div>
<h4>People</h4>
<ul data-bind="foreach: people">
<li>
Name at position  :

<a href="#" data-bind="click: $parent.removePerson">Remove</a>
</li>
</ul>
<button data-bind="click: addPerson">Add</button>

只传递一个字符串作为组件名称,比提供任何参数。例如:

<ul data-bind="foreach: planets">
<li>
Planet: <b data-bind="text: name"> </b>
<div data-bind="if: capital">
Capital: <b data-bind="text: capital.cityName"> </b>
</div>
</li>
</ul>
<script>
ko.applyBindings({
planets: [
{ name: 'Mercury', capital: null }, 
{ name: 'Earth', capital: { cityName: 'Barnsley' } } 
]
});
</script>

视图模型源码:

视图模型源码:

<div data-bind='component: "my-component"'></div>

备注:使用无容器的if绑定(if虚拟绑定)

function AppViewModel() {
var self = this;
self.twitterName = ko.observable('@example');
self.resultData = ko.observable(); // No initial value
self.getTweets = function() {
var name = self.twitterName(),
simulatedResults = [
{ text: name + ' What a nice day.' },
{ text: name + ' Building some cool apps.' },
{ text: name + ' Just saw a famous celebrity eating lard. Yum.' }
];
self.resultData({ retrievalDate: new Date(), topTweets: simulatedResults });
}
self.clearResults = function() {
self.resultData(undefined);
}
}
ko.applyBindings(new AppViewModel());
function AppViewModel() {
var self = this;

self.people = ko.observableArray([
{ name: 'Bert' },
{ name: 'Charles' },
{ name: 'Denise' }
]);
self.addPerson = function() {
self.people.push({ name: "New at " + new Date() });
};
self.removePerson = function() {
self.people.remove(this);
}
}
ko.applyBindings(new AppViewModel());

如果你觉得这种写法有些死板的话,也可以传递一个监控属性,用其值作为组件名称。待以后组件名变化的时候,直接修改监控属性值即可:

像之前的虚拟绑定一样,同样使用<!– ko –>和<!– /ko
–>进行。虚拟绑定适用于不改变UI元素的情况。

备注:with的无容器绑定(虚拟绑定)

备注1:使用$data

<div data-bind='component: observableWhoseValueIsAComponentName'></div>
<ul>
<li>This item always appears</li>
<!-- ko if: someExpressionGoesHere -->
<li>I want to make this item present/absent dynamically</li>
<!-- /ko -->
</ul>

像if、foreach等的虚拟绑定一样,with绑定也一样。使用<!– ko
–>和<!– /ko –>进行。

如前两个示例中,foreach后面所跟的是要循环的监控属性数组名称,而foreach内部所跟随的是监控属性数组的项目,例如firstName和lastName。

2.完整语法:

ifnot绑定

<ul>
<li>Header element</li>
<!-- ko with: outboundFlight -->
...
<!-- /ko -->
<!-- ko with: inboundFlight -->
...
<!-- /ko -->
</ul>

当你想引用监控属性数组本身的时候,就可以使用这个特殊的上下文$data,他所指的就是监控属性数组本身。

提供完整的组件参数,参数如下:

ifnot绑定是if绑定的逆向表达,格式与if绑定一样,只是判断结果与if整好相反。就像等于和不等于一样。例如:

以上所述是小编给大家介绍的KnockoutJS 3.X API
第四章之数据控制流with绑定,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

例如,你的监控属性数组中的项目没有明确的项目名称:

name – 注入组件的名称。可使用字符串或是监控属性。

<div data-bind="ifnot: someProperty">...</div>

您可能感兴趣的文章:

  • KnockoutJS 3.X API
    第四章之数据控制流foreach绑定
  • KnockoutJS 3.X API
    第四章之数据控制流if绑定和ifnot绑定
  • KnockoutJS 3.X API
    第四章之数据控制流component绑定
  • KnockoutJS 3.X API
    第四章之click绑定
  • KnockoutJS 3.X API
    第四章之事件event绑定
  • KnockoutJS 3.X API
    第四章之表单submit、enable、disable绑定
  • KnockoutJS 3.X API
    第四章之表单value绑定
  • BootstrapTable与KnockoutJS相结合实现增删改查功能【二】
  • BootstrapTable与KnockoutJS相结合实现增删改查功能【一】
  • KnockoutJS 3.X API
    第四章之表单textInput、hasFocus、checked绑定
<ul data-bind="foreach: months">
<li>
The current item is: <b data-bind="text: $data"></b>
</li>
</ul>
<script type="text/javascript">
ko.applyBindings({
months: [ 'Jan', 'Feb', 'Mar', 'etc' ]
});
</script>

params – 一组参数对象。通常,这是一个包含多个参数的键值对。

其等效写法为:

如何你愿意的话,也可以使用$data来引用监控数组属性中的项目,例如:

例如:

<div data-bind="if: !someProperty()">...</div>
<td data-bind="text: $data.firstName"></td>
<div data-bind='component: {
name: "shopping-cart",
params: { mode: "detailed-list", items: productsList }
}'></div>

有人会说使用if绑定是足够了。为毛还要ifnot绑定。原因是有很多强迫症患者喜欢这种ifnot的绑定方式,看起来更易懂,代码更整洁。

其实这是多此一举的。因为firstName的默认前缀就是$data,所以一般可以省略不写。

备注1:仅模板式的component

以上所述是小编给大家介绍的KnockoutJS 3.X API
第四章之数据控制流if绑定和ifnot绑定,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

备注2:使用$index、$parent和其他的上下文标记

通常的component绑定具有ViewModel和Template,但是这并不是必须的,有些时候一个component可能只包含一个Template。例如:

您可能感兴趣的文章:

  • KnockoutJS 3.X API
    第四章之数据控制流foreach绑定
  • KnockoutJS 3.X API
    第四章之数据控制流with绑定
  • KnockoutJS 3.X API
    第四章之数据控制流component绑定
  • KnockoutJS 3.X API
    第四章之click绑定
  • KnockoutJS 3.X API
    第四章之事件event绑定
  • KnockoutJS 3.X API
    第四章之表单submit、enable、disable绑定
  • KnockoutJS 3.X API
    第四章之表单value绑定
  • BootstrapTable与KnockoutJS相结合实现增删改查功能【二】
  • BootstrapTable与KnockoutJS相结合实现增删改查功能【一】
  • KnockoutJS 3.X API
    第四章之表单textInput、hasFocus、checked绑定

你可能会发现,在示例2中使用了$index来代替了监控属性数组的索引值(从0开始),当然$index是一个监控属性,他会根据数据的变化而自动变化,就像示例2中展示的一样。

ko.components.register('special-offer', {
template: '<div class="offer-box" data-bind="text: productName"></div>'
});

而$parent所代表的是在foreach绑定循环外的某个绑定属性,例如:

可以使用注入的方式,将视图模型注入给Template:

<h1 data-bind="text: blogPostTitle"></h1>
<ul data-bind="foreach: likes">
<li>
<b data-bind="text: name"></b> likes the blog post <b data-bind="text: $parent.blogPostTitle"></b>
</li>
</ul>
<div data-bind='component: {
name: "special-offer-callout",
params: { productName: someProduct.name }
}'></div>

备注3:使用“as”给foreach绑定项目起个别名

在或者使用客户元素(以后的高级章节讲解)进行注入视图模型。

在备注1中,使用$data.varibale的方式访问的监控属性数组的项目,但在有些时候你可以需要给这些项目起个别名,那就是可以使用as,例如:

<special-offer params='productName: someProduct.name'></special-offer>
<ul data-bind="foreach: { data: people, as: 'person' }"></ul>

如上例子,HTML标记为模板名称,其属性params中注入视图模型。

现在,只要在foreach循环中,使用person,就可以访问数组中的元素了。

备注2:component虚拟绑定

也有些嵌套使用的例子,这中会更加复杂一些,例如:

如同之前章节的虚拟绑定一样,同样是使用<!– ko –>和<!– /ko
–>这种方式实现虚拟绑定,来达到不更改DOM元素的目的

<ul data-bind="foreach: { data: categories, as: 'category' }">
<li>
<ul data-bind="foreach: { data: items, as: 'item' }">
<li>
:

</li>
</ul>
</li>
</ul>
<script>
var viewModel = {
categories: ko.observableArray([
{ name: 'Fruit', items: [ 'Apple', 'Orange', 'Banana' ] },
{ name: 'Vegetables', items: [ 'Celery', 'Corn', 'Spinach' ] }
])
};
ko.applyBindings(viewModel);
</script>
<!-- ko component: "message-editor" -->
<!-- /ko -->

备注4:不使用foreach容器并生产内容

传参的例子:

在某些情况下,可能需要复制容器标签的内容,例如生成如下DOM:

<!-- ko component: {
name: "message-editor",
params: { initialText: "Hello, world!", otherParam: 123 }
} -->
<!-- /ko -->
<ul>
<li class="header">Header item</li>
<!-- The following are generated dynamically from an array -->
<li>Item A</li>
<li>Item B</li>
<li>Item C</li>
</ul>

备注3:传递标记到component绑定

像这种情况,我们就无法在ul标签中使用foreach绑定,解决这个问题的方法就是使用无容器的foreach绑定:

<div data-bind="component: { name: 'my-special-list', params: { items: someArrayOfPeople } }">
<!-- Look, here's some arbitrary markup. By default it gets stripped out
and is replaced by the component output. -->
The person <em data-bind="text: name"></em>
is <em data-bind="text: age"></em> years old.
</div>
<ul>
<li class="header">Header item</li>
<!-- ko foreach: myItems -->
<li>Item </li>
<!-- /ko -->
</ul>
<script type="text/javascript">
ko.applyBindings({
myItems: [ 'A', 'B', 'C' ]
});
</script>

如上例子中,既有component绑定,也有一些DOM元素,当绑定后,my-special-list组件将会和这些DOM元素组成一个新的UI界面。在未来高级章节中,我们将会提到一个带有DOM标记的自定义companent绑定的例子。尽情期待。先卖个关子~。

这里使用虚拟元素容器,<!– ko –>和<!– /ko
–>。就想之前章节提到的虚拟绑定一样。

内存管理(了解即可,切勿钻牛角尖)

备注5:检测并处理数组变化

您的视图模型类可能有一个dispose函数。如果得以运行,KO将调用这个函数在内存中删除组件,并从DOM中删除。

当您修改模型数组的内容(通过添加,移动或删除其项),在foreach绑定使用一个有效的差分算法计算方法当出发生了什么变化的时候。

在一下情况,您必须使用dispose以释放垃圾收回资源。例如:

当您添加数组项,foreach会使您的模板的新副本,并将其插入到现有的DOM
当你删除数组项,foreach将直接删除相应的DOM元素
当你重新排序数组项(保持相同的对象实例),foreach通常只要将相应的DOM元素融入自己的新位置

setInterval 回调后,需要明确清除。

备注6:销毁项目

使用clearInterval(handle)去清除他们,否则视图模型在内存常驻。

有时你可能想为数据项目做删除标记,但实际上并不真正删除该项目。这中方式被称为非破坏性的删除。

ko.computed 回调后,直到明确设置成从它们的依赖接收通知。

默认情况下,foreach绑定将跳过(即隐藏)标记为删除任何数组项。如果你想显示这些项目,使用includeDestroyed选项。例如,

如果一个依赖关系是外部的对象,那么一定要使用.dispose()来释放计算监控属性,否则(也可能你的视图模型)将在内存常驻。另外,可以考虑使用一个pureComputed,以避免人工处理的需求。

<div data-bind='foreach: { data: myArray, includeDestroyed: true }'>
...
</div>

Subscriptions 回掉后,需要明确清除。

备注7:使用动画过渡,提高用户体验

如果您已经预订到外部观察时,一定要使用.dispose(),否则回调(也可能您的视图模型)将在内存中常驻。

如果您需要在生成的DOM元素运行一些定制逻辑,你可以使用afterRender/
afterAdd/beforeRemove/ beforeMove/ afterMove这些回调函数。

例如:

下面是一个使用afterAdd的一个简单的例子,应用经典的“黄色淡出”的效果,以新增项目。它需要的jQuery插件的颜色,使背景色彩的动画。

var someExternalObservable = ko.observable(123);
function SomeComponentViewModel() {
this.myComputed = ko.computed(function() {
return someExternalObservable() + 1;
}, this);
this.myPureComputed = ko.pureComputed(function() {
return someExternalObservable() + 2;
}, this);
this.mySubscription = someExternalObservable.subscribe(function(val) {
console.log('The external observable changed to ' + val);
}, this);
this.myIntervalHandle = window.setInterval(function() {
console.log('Another second passed, and the component is still alive.');
}, 1000);
}
SomeComponentViewModel.prototype.dispose = function() {
this.myComputed.dispose();
this.mySubscription.dispose();
window.clearInterval(this.myIntervalHandle);
// this.myPureComputed doesn't need to be manually disposed.
}
ko.components.register('your-component-name', {
viewModel: SomeComponentViewModel,
template: 'some template'
});

澳门威尼斯人赌场 4

以上所述是小编给大家介绍的KnockoutJS 3.X API
第四章之数据控制流component绑定,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

源码如下:

您可能感兴趣的文章:

  • KnockoutJS 3.X API
    第四章之数据控制流foreach绑定
  • KnockoutJS 3.X API
    第四章之数据控制流if绑定和ifnot绑定
  • KnockoutJS 3.X API
    第四章之数据控制流with绑定
  • KnockoutJS 3.X API
    第四章之click绑定
  • KnockoutJS 3.X API
    第四章之事件event绑定
  • KnockoutJS 3.X API
    第四章之表单submit、enable、disable绑定
  • KnockoutJS 3.X API
    第四章之表单value绑定
  • BootstrapTable与KnockoutJS相结合实现增删改查功能【二】
  • BootstrapTable与KnockoutJS相结合实现增删改查功能【一】
  • KnockoutJS 3.X API
    第四章之表单textInput、hasFocus、checked绑定
<ul data-bind="foreach: { data: myItems, afterAdd: yellowFadeIn }">
<li data-bind="text: $data"></li>
</ul>
<button data-bind="click: addItem">Add</button>
<script type="text/javascript">
ko.applyBindings({
myItems: ko.observableArray([ 'A', 'B', 'C' ]),
yellowFadeIn: function(element, index, data) {
$(element).filter("li")
.animate({ backgroundColor: 'yellow' }, 200)
.animate({ backgroundColor: 'white' }, 800);
},
addItem: function() { this.myItems.push('New item'); }
});
</script>

一些具体的细节

afterRender-当foreach第一次初始化执行的回调函数。KO提供下列参数回调:

插入的DOM元素的数组

数据项

afterAdd-当foreach添加新项目后的回调函数。KO提供下列参数回调:

DOM节点
添加的数组元素的索引
添加的数组元素

beforeRemove-当一个数组项已被删除的回调函数。这里最明显的用jQuery的$(domNode).fadeOut()动画去除相应的DOM节点。KO提供下列参数回调:

删除一个DOM节点

被删除的数组元素的索引

删除的数组元素

beforeMove-当一个数组项在数组中已经改变了位置的回调函数,但之前相应的DOM节点已被移动。需要注意的是beforeMove适用于所有的数组元素的指标发生了变化,因此,如果你在一个数组的开头插入一个新的项目,然后回调(如果指定)将触发所有其他元素,因为它们的索引位置增加了一个。您可以使用beforeMove存储在受影响元素的原始屏幕坐标,这样你可以在afterMove回调动画动作。KO提供下列参数回调:

可能是移动的DOM节点

移动的数组元素的索引

移动的数组元素

afterMove-数组项在数组中已经改变位置的回调函数,KO提供下列参数回调:

可能已经移动的DOM节点

移动的数组元素的索引

移动的数组元素

以上所述是小编给大家介绍的KnockoutJS 3.X API
第四章之数据控制流foreach绑定,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

您可能感兴趣的文章:

  • KnockoutJS 3.X API
    第四章之数据控制流if绑定和ifnot绑定
  • KnockoutJS 3.X API
    第四章之数据控制流with绑定
  • KnockoutJS 3.X API
    第四章之数据控制流component绑定
  • KnockoutJS 3.X API
    第四章之click绑定
  • KnockoutJS 3.X API
    第四章之事件event绑定
  • KnockoutJS 3.X API
    第四章之表单submit、enable、disable绑定
  • KnockoutJS 3.X API
    第四章之表单value绑定
  • BootstrapTable与KnockoutJS相结合实现增删改查功能【二】
  • BootstrapTable与KnockoutJS相结合实现增删改查功能【一】
  • KnockoutJS 3.X API
    第四章之表单textInput、hasFocus、checked绑定

相关文章