淘汰高级声明javascript"用“-喜欢
Knockout advanced declaration javascript "with"-like
我遇到了一些问题,需要在子元素(如$parents、$parent)中的任何地方都可以访问自定义变量,我们可以引用这些变量。示例:
<div data-bind:"addThisVariable: { name: '$hello', value: somethingTimeConsuming() }">
<div data-bind="foreach: something">
<span data-bind="text: $hello.stringReference">
</span>
</div>
</div>
我想知道Knockout是否已经提供了它,或者是否有人知道如何实现这一点。
我想用"$something"这样的变量填充上下文及其子上下文
但在淘汰赛中,对于我所宣称的所有环境和儿童环境。因此,我可以完成可能耗时的任务,而不必每次都重新运行它们。
编辑:我不想要"with:$something"绑定,它不能回答我的答案
它想要一个临时的var,我需要它来填充子上下文,就像我们对所做的那样
.forEach(function(item){
var somethingCalculated = 1234;
item.someArray.forEach(function(subItem) {
var somethingElse = somethingCalculated + 567;
}
})
不久前,我为自己创建了一个名为let
的简单绑定,它可以满足您的需要。这是:
ko.bindingHandlers['let'] = {
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
// Make a modified binding context, with extra properties, and apply it to descendant elements
var innerContext = bindingContext.extend(valueAccessor);
ko.applyBindingsToDescendants(innerContext, element);
return { controlsDescendantBindings: true };
}
};
ko.virtualElements.allowedBindings['let'] = true;
你会这样使用它:
<div data-bind:"let: { $hello: somethingTimeConsuming() }">
<div data-bind="foreach: something">
<span data-bind="text: $hello.stringReference">
</span>
</div>
</div>
ko.bindingHandlers['let'] = {
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
// Make a modified binding context, with extra properties, and apply it to descendant elements
var innerContext = bindingContext.extend(valueAccessor);
ko.applyBindingsToDescendants(innerContext, element);
return { controlsDescendantBindings: true };
}
};
ko.virtualElements.allowedBindings['let'] = true;
(function() {
var vm = {
foo: ko.observable("foo"),
bar: ko.observable("bar"),
list: ko.observableArray([
'one', 'two', 'three'
])
};
vm.hello = ko.pureComputed(function() {
return vm.foo() + vm.bar();
});
ko.applyBindings(vm);
})();
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div data-bind="let: { $hello: hello() }">
<div data-bind="foreach: list">
<span data-bind="text: $data"></span><span data-bind="text: $hello"></span>
</div>
</div>
这两个选项都不能为您提供JavaScript的with
(但是,JavaScript的with
有一些非常重要的维护问题),但这里有几个选项:
你最好的选择可能是在容器甚至根虚拟机上计算。
yourVm.hello = ko.computed({
pure: true, // If it is, that is
read: function() {
// complex stuff here
}
});
示例:
(function() {
"use strict";
var vm = {
foo: ko.observable("foo"),
bar: ko.observable("bar"),
list: ko.observableArray([
'one', 'two', 'three'
])
};
vm.hello = ko.computed({
pure: true,
owner: this,
read: function() {
return this.foo() + this.bar();
}
});
ko.applyBindings(vm, document.body);
})();
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout/3.1.0/knockout-min.js"></script>
<div data-bind="foreach: list">
<span data-bind="text: $data"></span><span data-bind="text: $parent.hello"></span>
</div>
只有当它所接触的可观测值发生变化时,计算的值才会被重新赋值。
如果你把它放在根上,那么$root.hello
将始终引用它
但我认为创建一个自定义绑定是可能的,它使用的语法非常像您所展示的,但我不建议这样做。大致如下(完全未经测试—嗯,whaddyaknow,它有效,见下文):
ko.bindingHandlers.addThisVariable = {
update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var value = ko.unwrap(valueAccessor());
bindingContext.$data[ko.unwrap(value.name)] = ko.unwrap(value.value);
}
};
示例(但再次强调,我真的认为我会采用计算):
(function() {
"use strict";
ko.bindingHandlers.addThisVariable = {
update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var value = ko.unwrap(valueAccessor());
bindingContext.$data[ko.unwrap(value.name)] = ko.unwrap(value.value);
}
};
var vm = {
foo: ko.observable("foo"),
bar: ko.observable("bar"),
list: ko.observableArray([
'one', 'two', 'three'
])
};
ko.applyBindings(vm, document.body);
})();
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout/3.1.0/knockout-min.js"></script>
<div data-bind="addThisVariable: { name: '$hello', value: foo() + bar() }, foreach: list">
<span data-bind="text: $data"></span><span data-bind="text: $parent.$hello"></span>
</div>
这只是将其添加到当前VM中(因此内部的with
或foreach
绑定需要$parent
或$parent.$parent
或其他),但它仍然为您提供了可以在HTML块中引用的本地内容。
Knockouts foreach
绑定有一个as
选项,可以执行您想要的操作。如果你有一个"somethings"数组,并且你希望能够将它们引用为$something.whatever
,那么
<!-- ko foreach: {data: arrayOfSomethings, as: '$something'} -->
<span data-bind="text: $something.foo"></span> <!-- works in any child context -->
<!-- /ko -->
另一方面,如果你只有一个"某物"。。。老实说,我可能会推荐迈克尔·贝斯特的let
绑定。。。但是,如果你只想要一个工作并且不需要自定义绑定处理程序的东西。。。
<!-- ko foreach: {data: [something], as: '$something'} --> <!-- ugly but it works -->
<span data-bind="text: $something.foo"></span> <!-- works in any child context -->
<!-- /ko -->
(附带说明,我实际上不建议使用"$something"作为您的名称;我会将$前缀留给敲除定义的东西,并直接称您的东西为"something)
- 铬:“;未捕获的语法错误:意外的标记:"
- 可以设置“;文件名"发生错误时显示的内联脚本标记的
- JS表单提交"无法使用Chrome数据保护程序加载此页面.尝试重新加载页面.调试信息:POST CISmtuK
- 检测电话窃听,即:<a href="电话:xxx">在UIWebview上
- 使用“+="操作人员
- //而不是在src=“”上使用http://"属性
- "未捕获的语法错误:意外的标记}"
- 可以<脚本类型=“;text/javascript”>window.location=“/"</
- "实例范围”;TypeScript类的getter/setter
- Javascript复选框函数:;缺少:在属性id之后"
- "“;变量未引用正确的对象
- "日期“;AJAX请求返回的类型值未定义
- 得到"TypeError:无法读取属性'filename'未定义的“;调用“npm start
- Soundcloud api"未捕获的类型错误:无法读取属性'uri'“未定义”;
- "工具提示"jQuery插件坏了
- "锻造;React中的表达式
- 图像可以从源<img src=""/>.TEXT可以在没有javascript的情况下从外部
- 如何提取“;href"最近列表项中的属性值
- 淘汰高级声明javascript"用“-喜欢
- 我真的很喜欢红宝石般的方式;isACar"方法名称,但如何在js中完成