Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

关于knockout知识点整理 #113

Open
Seasons123 opened this issue May 14, 2020 · 5 comments
Open

关于knockout知识点整理 #113

Seasons123 opened this issue May 14, 2020 · 5 comments

Comments

@Seasons123
Copy link
Owner

Seasons123 commented May 14, 2020

一、激活Knockout:applyBindings
使用KO创建一个View Model,仅仅只需要声明一个JavaScript对象,例如:
var myViewModel = {personName: 'Bob',personAge: 123};
data-bind属性并不是HTML固有对象,但使用它是完全正确的(这是完全遵守HTML5,尽管有验证器指出这是一个无法验证的属性,但在HTML4当中使用是不会造成任何问题的)。但浏览器并不知道它是什么意思,所以你需要激活Knockout来使其生效。
激活Knockout,只需要将下面的代码加到<script>标签中就可以了:

// Knockout调用applyBindings激活myViewModel(即把myViewModel和View中的声明式绑定data-bind接洽关系起来) 
ko.applyBindings(myViewModel);

你可以将这个代码放到文档底部,或者放在顶部包含在DOM处理完成诸如JQuery的$函数方法中。
下面介绍下ko.applyBindings操作时使用的是什么样的参数:第一个参数是你想激活KO时用于声明式绑定的View Model对象;第二个参数(可选),你可以使用第二个参数来设置要使用data-bind属性的HTML元素或容器。例如:ko.applyBindings(myViewModel, document.getElementById('someElementId'))它限制了只有ID为someElementId的元素才能激活使用KO功能,当你在一个页面中声明了多个View Model来绑定不同的界面区域时,这样限制是很有好处的。

@Seasons123
Copy link
Owner Author

二、Observables
上面,你已经看到如何创建一个基本的数据模型以及如何利用绑定来显示它的属性。但是KO最重要的一个属性就是当View Model发生变化时能够自动的更新UI界面。KO是如何能够知道你的View Model已经发生改变了呢?答案是:你需要将你的model属性声明成observable的, 因为它是非常特殊的JavaScript 对象,能够通知用户它的改变以及自动检测依赖关系。
例如:重写上述例子中的View Model为以下代码:

var myViewModel = {
personName: ko.observable('Bob'),
personAge: ko.observable(123)
};

你根本不需要对View进行更改,所有的data-bind语法依然正常工作。所不同的是,现在它能够自动检测变化,并通知它自动更新界面(View)。

@Seasons123
Copy link
Owner Author

Seasons123 commented May 14, 2020

三、1.计算属性 Computed Observable
如果你已经有了一个监控属性firstName和lastName,如果你想显示全名该怎么做呢?这个时候你就可以通过计算属性来实现,这个方法依赖于一个或多个监控属性,如果任何依赖对象发生改变他们就会跟着改变。
例如,下面的 view model:

function AppViewModel(){
 this.firstName=ko.observable('Bob');
 this.lastName=ko.observable('Smith');
}

你可以添加一个计算属性来返回全名,例如:

function AppViewModel(){
 // ... leave firstName and lastName unchanged ... 
this.fullName=ko.computed(function(){
   return this.firstName()+" "+this.lastName();
 },this);}

下面你就可以将它绑定到UI对象上了,如:
Thenameis<span data-bind="text: fullName"></span>
当firstName或者lastName变化,它将会随时更新(当依赖关系发生变化,你的计算函数就会被调用,并且它的值都会更新到UI对象或其他的依赖属性上去)。

@Seasons123
Copy link
Owner Author

Seasons123 commented May 14, 2020

三、2.Computed Observable 依赖跟踪是如何工作的
初学者可以不必知道这一点,但是高级开发人员可以通过这节来了解依赖监控属性可以通过KO自动跟踪并被更新到UI上。
事实上它是很简单的,甚至简单的有点可爱,跟踪算法是这样的:

1、 当你声明一个依赖属性时,KO会立即调用求值算法得到其初始值;
2、 当你的计算函数运行的时候,KO会把监控属性通过计算得到的值都记录在一个Log中;
3、 当你的计算结束的时候,KO会订阅能够访问的监控属性或依赖属性,订阅的回调函数是重新运行你的计算函数,循环整个过程,回到步骤1(并且注销不再使用的订阅);
4、 KO会通知所有的订阅者,你的依赖属性已经被设置了新值。

所以说,KO并不仅仅是在第一次执行计算函数时检测你的依赖项,它每次都会检测。这意味着,你的依赖是可以动态的,举例来说:依赖A能决定你是否也依赖于B或C,这时候只有当A或者你选择的B或者C发生变化时计算函数才能运行。你不需要定义依赖关系:在代码运行时会自动检测到。
另外声明绑定是依赖属性的一种简单优美的实现。所以,一个绑定是读取监控属性的值,这个绑定变成这个监控属性的依赖,当监控属性发生改变的时候,会引起这个绑定被重新计算。

@Seasons123
Copy link
Owner Author

Seasons123 commented May 14, 2020

四、一种简化的流行惯例
当你需要全程跟踪this时,下面的写法是一种很流行的惯例:如果你将你的viewmodel's结构this作为一个变量复制一份(传统称之为self),在以后你可以使用self来代表viewmodel而不必担心它重定义或指别的东西。例如:

function AppViewModel(){
 var self=this;
 self.firstName=ko.observable('Bob');
 self.lastName=ko.observable('Smith');
 self.fullName=ko.computed(function(){
 return self.firstName()+" "+self.lastName();
 });
}

由于self在闭合的方法内部也是可以捕获到的,所以在任何嵌套函数当中,它仍然可用并保持一致性。 如ko.computed求值,当涉及到事件处理时它依然显得很有用。

@Seasons123
Copy link
Owner Author

五、html绑定
html绑定到DOM元素上,使得该元素显示的HTML值为你绑定的参数。如果在你的view model里声明HTML标记并且render的话,那非常有用。

<div data-bind="html: details"></div> 
<script type="text/javascript">
var viewModel = {        
details: ko.observable() // Initially blank    
};    
viewModel.details("<em>For further details, 
view the report <a href='report.html'>here</a>.</em>"); // HTML content appears
</script>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant