The*_*ook 3 javascript knockout.js durandal
我正在尝试将jqplot与Durandal和淘汰赛一起使用.我在Durandal小组(https://groups.google.com/forum/#!topic/durandaljs/WXBiSK3WmIs)上找到了一篇解决此问题的帖子,但它使用的视图模型构造完全让我感到困惑,因为它将一个"prototype.activate"方法添加到构造函数中,这对我来说是全新的(当我尝试使用它时不起作用).
任何人都可以试着告诉我如何使用我的揭示模块模式使用Rob的例子如下所示?
我的viewmodel:
define(['globalVar', 'services/datacontext', 'services/calccontext"], function (globalVar, datacontext, calcContext) {
var activate = function () {
return datacontext.newEntity(articleResults, "articleVersionResults");
};
var calcAll = function () {
//can be called externally and recalcs all
return individualImpactCalc('byWeightAndFactor', 'CO2e', articleResults().material_CO2e);
//will be more calls in here soon
};
var individualImpactCalc = function (calcName, fac, calcObservable) {
return calcContext.indCalc(calcName, fac, calcObservable, globalVar.components()); //puts result straight into observable
};
var vm = {
activate: activate,
calcAll: calcAll
};
return vm;
});
Run Code Online (Sandbox Code Playgroud)
Rob的代码示例:
define(["jquery", "knockout"], function($, ko){
// constructor
var ctor = function () {
var self = this;
// properties
self.chartConfig = {};
};
ctor.prototype.activate = function(id, page) {
var self = this;
// get data from database
self.chartConfig.data([
[300, 295, 290],
[320, 320, 320],
[260, 265, 260]
]);
self.chartConfig.title("Forecast net operating costs");
self.chartConfig.seriesColors(["#0026FF", "#FF6A00", "#606060"]);
self.chartConfig.series([
{ label: "Foo" },
{ label: "Bar" },
{ label: "Baz" }
]);
self.chartConfig.ticks(["Apr 13", "May 13", "Jun 13"]);
};
ctor.prototype.compositionComplete = function (view, parent) {
var self = this;
var c = self.chartConfig;
self.jqChart = $.jqplot("chart", c.data(), ...
// example to change the data
setTimeout(function () {
self.chartConfig.data([
[280, 280, 280],
[280, 280, 280],
[280, 280, 280]
]);
}, 4000);
};
return ctor;
});
Run Code Online (Sandbox Code Playgroud)
编辑1:问题是compositioncomplete没有触发.此视图模型是主页面中的子视图.不知道这是否会影响事情?
我的viewmodel现在是:
define(['globalVar', 'services/datacontext', 'services/calccontext', "jquery", "knockout"], function (globalVar, datacontext, calcContext, $, ko) {
// constructor
var ctor = function () {
var self = this;
// properties
self.chartConfig = {
data: ko.observableArray([]),
title: ko.observable(),
seriesColors: ko.observableArray([]),
series: ko.observableArray([]),
ticks: ko.observableArray([])
};
// subscriptions
self.chartConfig.data.subscribe(function (newValue) {
var opts = {
data: newValue
};
if (self.jqChart) {
self.jqChart.replot(opts);
console.log("chart replotted", opts);
}
});
};
function setChartVars() {
var self = this;
// get data from database
self.chartConfig.data([
[300, 295, 290],
[320, 320, 320],
[260, 265, 260]
]);
self.chartConfig.title("Forecast net operating costs");
self.chartConfig.seriesColors(["#0026FF", "#FF6A00", "#606060"]);
self.chartConfig.series([
{ label: "Foo" },
{ label: "Bar" },
{ label: "Baz" }
]);
self.chartConfig.ticks(["Apr 13", "May 13", "Jun 13"]);
};
var activate = function () {
ctor();
setChartVars();
return datacontext.newEntity(articleResults, "articleVersionResults");
};
var compositionComplete = function () {
var self = this;
var c = self.chartConfig;
self.jqChart = $.jqplot("chart", c.data());
// example to change the data
setTimeout(function () {
self.chartConfig.data([
[280, 280, 280],
[280, 280, 280],
[280, 280, 280]
]);
}, 4000);
};
var calcAll = function () {
//can be called externally and recalcs all
//return res_mat_gwp();
return individualImpactCalc('byWeightAndFactor', 'CO2e', articleResults().material_CO2e);
};
var individualImpactCalc = function (calcName, fac, calcObservable) {
return calcContext.indCalc(calcName, fac, calcObservable, globalVar.components()); //puts result straight into observable
};
var vm = {
activate: activate,
compositionComplete: compositionComplete,
calcAll: calcAll,
editArticleVersion: globalVar.editArticleVersion,
articleResults: articleResults,
ctor: ctor
};
return vm;
});
Run Code Online (Sandbox Code Playgroud)
您必须了解返回单例视图模型和函数视图模型之间的根本区别.您还需要了解继承如何在JavaScript中工作,以掌握prototype属性背后的目的及其使用原因.
您已经了解了单例视图模型 - 这就是您一直在构建视图模型的方式,因此,您最熟悉它.另一种方法,你不太了解,是一种将"接口"返回到视图模型的方法,目的是实例化它们中的一个或多个.如果将viewmodel作为函数返回,则必须使用该new关键字对其进行实例化.让我用一个例子来说明这一点.
此示例viewmodel返回一个函数,而不是单例:
define([], function () {
var example = function (title) {
this.title = title;
};
example.prototype.activate = function (params) {
// do something with the params
};
return example;
});
Run Code Online (Sandbox Code Playgroud)
此viewmodel返回一个单例,并要求前一个作为依赖项:
define(['viewmodels/example'], function (Example) {
return {
exampleOne: new Example('This is a test!'),
exampleTwo: new Example('This is another test!')
};
});
Run Code Online (Sandbox Code Playgroud)
由于'viewmodels/example'返回一个函数,我们必须使用该new关键字来实例化它(注意:如果你在视图中使用合成绑定,Durandal会为你做这个).
双方exampleOne并exampleTwo具有独特的称号; 但是,他们有相同的activate()方法.这是该prototype物业的优势.此策略可应用于您希望重复的视图,但共享相同的激活代码,如模式对话框或小部件.