我已经为 CodeMirror 创建了自定义绑定(bind)。自定义绑定(bind)适用于简单的字符串,但在 foreach
绑定(bind)内,尽管添加了所有 HTML 和 CSS,但它不再被初始化。
这是一个工作片段:
var viewModel = {
options: {
mode: "text/x-csharp",
lineNumbers: true
},
//IT WORKS
fileContent: "public sealed class DictionaryAttribute : Attribute{}1",
//IT DOESN'T WORK
codes: ["public sealed class DictionaryAttribute : Attribute{}1"]
};
ko.bindingHandlers.codemirror = {
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
var options = viewModel.options || {};
options.value = ko.unwrap(valueAccessor());
var editor = CodeMirror(element, options);
editor.on('change', function(cm) {
var value = valueAccessor();
value(cm.getValue());
});
element.editor = editor;
}
};
ko.applyBindings(viewModel);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<link href="https://codemirror.net/lib/codemirror.css" rel="stylesheet" />
<script src="https://codemirror.net/lib/codemirror.js"></script>
<script src="https://codemirror.net/mode/clike/clike.js"></script>
<!-- This works -->
<div data-bind="codemirror: fileContent" style="width: 700px; height: 100px"></div>
<!-- This doesn't work -->
<div data-bind="foreach: codes">
<div data-bind="codemirror: $data" style="width: 700px; height: 100px"></div>
</div>
最佳答案
问题出在 var options = viewModel.options || {};
在您的自定义绑定(bind)中。 viewModel
参数指的是当前$data
在上下文中,不是 applyBindings
中使用的 viewModel 。它适用于简单的字符串,因为在这种情况下, viewModel
参数是主要viewModel
您传递给 applyBidnigs
的对象。里面foreach
, viewModel
将是每个 $data
在你的数组中。
所以,使用$root
bindingContext
的属性(property)参数代替。此外,viewModel
参数在 Knockout 3.x 中已弃用:
像这样:
var options = bindingContext.$root.options || {};
更新的代码片段:
var viewModel = {
options: {
mode: "text/x-csharp",
lineNumbers: true
},
//IT WORKS
fileContent: "public sealed class DictionaryAttribute : Attribute{}1",
//IT DOESN'T WORK
codes: ["public sealed class DictionaryAttribute : Attribute{}1"]
};
ko.bindingHandlers.codemirror = {
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
var options = bindingContext.$root.options || {};
options.value = ko.unwrap(valueAccessor());
var editor = CodeMirror(element, options);
editor.on('change', function(cm) {
var value = valueAccessor();
value(cm.getValue());
});
element.editor = editor;
}
};
ko.applyBindings(viewModel);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<link href="https://codemirror.net/lib/codemirror.css" rel="stylesheet" />
<script src="https://codemirror.net/lib/codemirror.js"></script>
<script src="https://codemirror.net/mode/clike/clike.js"></script>
<div data-bind="codemirror: fileContent" style="width: 700px; height: 100px"></div>
<div data-bind="foreach: codes">
<div data-bind="codemirror: $data" style="width: 700px; height: 100px"></div>
</div>
上面的代码适用于您的情况。但是,绑定(bind)期望顶部 $root
反对 options
属性(property)。另一种方法是添加 codeMirrorOptions
绑定(bind)参数并完全删除该依赖项。
var viewModel = {
options: {
mode: "text/x-csharp",
lineNumbers: true
},
//IT WORKS
fileContent: "public sealed class DictionaryAttribute : Attribute{}1",
//IT DOESN'T WORK
codes: ["public sealed class DictionaryAttribute : Attribute{}1"]
};
ko.bindingHandlers.codemirror = {
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
// use allBindings
var options = ko.unwrap(allBindings().codeMirrorOptions) || {};
options.value = ko.unwrap(valueAccessor());
var editor = CodeMirror(element, options);
editor.on('change', function(cm) {
var value = valueAccessor();
value(cm.getValue());
});
element.editor = editor;
}
};
ko.applyBindings(viewModel);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<link href="https://codemirror.net/lib/codemirror.css" rel="stylesheet" />
<script src="https://codemirror.net/lib/codemirror.js"></script>
<script src="https://codemirror.net/mode/clike/clike.js"></script>
<div data-bind="codemirror: fileContent, codeMirrorOptions:options" style="width: 700px; height: 100px"></div>
<div data-bind="foreach: codes">
<div data-bind="codemirror: $data, codeMirrorOptions:$parent.options" style="width: 700px; height: 100px"></div>
</div>
在这种情况下,自定义绑定(bind)独立于 viewModel。即使你的viewModel
不是 $root
对象,自定义绑定(bind)将起作用。
关于knockout.js - CodeMirror 自定义绑定(bind)在 "foreach"绑定(bind)内不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47567347/