将组件从现有 html 页面提取到外部文件
Extracting a component from an existing html page to external files
我有以下 html/js 现有工作代码,我想将它们提取到它们自己的文件中并使用 require.js.
加载它们
我的目标是将其组件化以便能够在其他地方使用它。
.html
...
<ul data-bind="foreach: selectedExams">
<li>
<select data-bind="options: $parent.availableExams, optionsText: 'examTypeName', optionsValue:'examTypeId', value: examtype"></select>
<select data-bind="options: exams, optionsText: 'examName', optionsValue:'examId',value: exam, enable:exams().length"></select>
<a href="#" data-bind="click: $parent.remove">Remove</a>
</li>
</ul>
<button data-bind="click: add">Add</button>
...
.js
var self = this;
...
self.availableExams = [...];
self.selectedExams = ko.observableArray([new selectedExam(self)]);
self.add = function () {
self.selectedExams.push(new selectedExam(self));
};
self.remove = function (exam) { self.selectedExams.remove(exam) }
...
起初看起来很简单,但我很困惑,因为viewmodel似乎需要完全重写。
因为我想试验看看它是如何工作的,所以在 docs 之后,我创建了一个单独的 .html 文件,其中包含上面显示的所需内容。
以及以下自主 .js 文件:
function ExamControlViewModel()
{
var self = this;
self.availableExams = [...];
self.selectedExams = ko.observableArray([new selectedExam(self)]);
self.add = function () {
self.selectedExams.push(new selectedExam(self));
};
self.remove = function (exam) { self.selectedExams.remove(exam) }
}
ko.applyBindings(new ExamControlViewModel());
接下来,我从原始 html/js 文件中删除了代码,并将以下内容添加到 js 文件中:
ko.components.register('exam-control', {
viewModel: { require: 'exam-control-viewmodel' },
template: { require: 'text!exam-control-view.html' }
})
它在运行时失败并出现以下错误:
"text" 的脚本错误,需要:text!exam-control-view。html_unnormalized2
http://requirejs.org/docs/errors.html#scripterror
显然我没有抓住要点,这不可能那么简单...可能吗?
感谢任何指导。
编辑 1:
我遵循了@JotaBe 的出色指导并得到了以下结果:
.js 文件
define([],function() {
function ExamControlViewModel()
{
var self = this;
self.availableExams = [...];
self.selectedExams = ko.observableArray([new selectedExam(self)]);
self.add = function () {
self.selectedExams.push(new selectedExam(self));
};
self.remove = function (exam) { self.selectedExams.remove(exam) }
}
return ExamControlViewModel;
});
html 文件:
=>开头
...
<script type='text/javascript' src='Scripts/knockout-3.4.0.js'></script>
<script type='text/javascript' src='Scripts/knockout.validation.js'></script>
<script type='text/javascript' src='Scripts/require.js'></script>
<script type='text/javascript' src='Scripts/text.js'></script>
...
=>组件代码被替换为(提问时忘了说)
<exam-control></exam-control>
现在在运行时,出现以下错误:
不匹配的匿名 define() 模块
我会在取得进展后再次更新此主题。
你应该包括text plugin for RequireJS
. Here我已经写了更详细的答案。
你必须做这些事情:
- 按照 AMD 模式导出模块构造函数
- 包含
require.js
文本插件,以便模板可以通过 require 加载
- 配置 require.js 以便它可以找到您的模板和脚本
- 注册组件
1。导出视图模型构造函数
导出构造函数的 AMD 模式如下所示:
define([/*dependencies*/],function() {
// define the constructor you want to export
function ExamControlViewModel() { ... }
// export it
return ExamControlViewModel;
});
这必须是您的 exam-control-viewmodel.js
文件的唯一内容。您不需要 applyBindings
:knockout 将复制模板内容并在加载脚本和模板时应用绑定。
我想你已经全局加载了 knockout
。如果您这样做了,请按照说明保留定义。但是,如果您使用 require.js
加载 ko
和相关内容(如插件),您应该通过在文件中进行以下更改将其作为依赖项包含在内:
define(['ko'],function(ko) {
当然,您需要正确的配置路径才能将 knockout 加载为 ko
。如果没有,您将必须指定整个文件名(和路径)。
2。包括 require.js 文本 lugin
require.js
text
插件可用 here, and here you can see the related documentation. You can install it by copying it or using any of the available packages formats, like Nuget or npm。
3。配置 require.js
您必须配置 require 才能找到文件,如 explained here。一定要特别注意baseUrl
.
4。注册组件
组件注册正确,您已经完成了。特别是 'text!exam-control-view.html'
指示 require.js
使用 text
插件加载模板。 .js
文件必须具有指定的名称。
由于 require.js
和插件的工作方式,正如您所做的那样,必须包含 .html
扩展名,并且必须删除 .js
。
如果您指定了正确的配置,将从指定的 baseUrl
读取文件。如果不是,则必须对其进行修改。如果加载不正确,您可以使用浏览器的控制台查找问题所在。
当然require.js
,使用组件前必须加载相关配置
我有以下 html/js 现有工作代码,我想将它们提取到它们自己的文件中并使用 require.js.
加载它们我的目标是将其组件化以便能够在其他地方使用它。
.html
...
<ul data-bind="foreach: selectedExams">
<li>
<select data-bind="options: $parent.availableExams, optionsText: 'examTypeName', optionsValue:'examTypeId', value: examtype"></select>
<select data-bind="options: exams, optionsText: 'examName', optionsValue:'examId',value: exam, enable:exams().length"></select>
<a href="#" data-bind="click: $parent.remove">Remove</a>
</li>
</ul>
<button data-bind="click: add">Add</button>
...
.js
var self = this;
...
self.availableExams = [...];
self.selectedExams = ko.observableArray([new selectedExam(self)]);
self.add = function () {
self.selectedExams.push(new selectedExam(self));
};
self.remove = function (exam) { self.selectedExams.remove(exam) }
...
起初看起来很简单,但我很困惑,因为viewmodel似乎需要完全重写。
因为我想试验看看它是如何工作的,所以在 docs 之后,我创建了一个单独的 .html 文件,其中包含上面显示的所需内容。
以及以下自主 .js 文件:
function ExamControlViewModel()
{
var self = this;
self.availableExams = [...];
self.selectedExams = ko.observableArray([new selectedExam(self)]);
self.add = function () {
self.selectedExams.push(new selectedExam(self));
};
self.remove = function (exam) { self.selectedExams.remove(exam) }
}
ko.applyBindings(new ExamControlViewModel());
接下来,我从原始 html/js 文件中删除了代码,并将以下内容添加到 js 文件中:
ko.components.register('exam-control', {
viewModel: { require: 'exam-control-viewmodel' },
template: { require: 'text!exam-control-view.html' }
})
它在运行时失败并出现以下错误:
"text" 的脚本错误,需要:text!exam-control-view。html_unnormalized2 http://requirejs.org/docs/errors.html#scripterror
显然我没有抓住要点,这不可能那么简单...可能吗?
感谢任何指导。
编辑 1:
我遵循了@JotaBe 的出色指导并得到了以下结果:
.js 文件
define([],function() {
function ExamControlViewModel()
{
var self = this;
self.availableExams = [...];
self.selectedExams = ko.observableArray([new selectedExam(self)]);
self.add = function () {
self.selectedExams.push(new selectedExam(self));
};
self.remove = function (exam) { self.selectedExams.remove(exam) }
}
return ExamControlViewModel;
});
html 文件: =>开头
...
<script type='text/javascript' src='Scripts/knockout-3.4.0.js'></script>
<script type='text/javascript' src='Scripts/knockout.validation.js'></script>
<script type='text/javascript' src='Scripts/require.js'></script>
<script type='text/javascript' src='Scripts/text.js'></script>
...
=>组件代码被替换为(提问时忘了说)
<exam-control></exam-control>
现在在运行时,出现以下错误:
不匹配的匿名 define() 模块
我会在取得进展后再次更新此主题。
你应该包括text plugin for RequireJS
. Here我已经写了更详细的答案。
你必须做这些事情:
- 按照 AMD 模式导出模块构造函数
- 包含
require.js
文本插件,以便模板可以通过 require 加载
- 配置 require.js 以便它可以找到您的模板和脚本
- 注册组件
1。导出视图模型构造函数
导出构造函数的 AMD 模式如下所示:
define([/*dependencies*/],function() {
// define the constructor you want to export
function ExamControlViewModel() { ... }
// export it
return ExamControlViewModel;
});
这必须是您的 exam-control-viewmodel.js
文件的唯一内容。您不需要 applyBindings
:knockout 将复制模板内容并在加载脚本和模板时应用绑定。
我想你已经全局加载了 knockout
。如果您这样做了,请按照说明保留定义。但是,如果您使用 require.js
加载 ko
和相关内容(如插件),您应该通过在文件中进行以下更改将其作为依赖项包含在内:
define(['ko'],function(ko) {
当然,您需要正确的配置路径才能将 knockout 加载为 ko
。如果没有,您将必须指定整个文件名(和路径)。
2。包括 require.js 文本 lugin
require.js
text
插件可用 here, and here you can see the related documentation. You can install it by copying it or using any of the available packages formats, like Nuget or npm。
3。配置 require.js
您必须配置 require 才能找到文件,如 explained here。一定要特别注意baseUrl
.
4。注册组件
组件注册正确,您已经完成了。特别是 'text!exam-control-view.html'
指示 require.js
使用 text
插件加载模板。 .js
文件必须具有指定的名称。
由于 require.js
和插件的工作方式,正如您所做的那样,必须包含 .html
扩展名,并且必须删除 .js
。
如果您指定了正确的配置,将从指定的 baseUrl
读取文件。如果不是,则必须对其进行修改。如果加载不正确,您可以使用浏览器的控制台查找问题所在。
当然require.js
,使用组件前必须加载相关配置