我正在尝试将jqplot与Durandal和淘汰赛一起使用。我发现Rob在Durandal组(https://groups.google.com/forum/#!topic/durandaljs/WXBiSK3WmIs)上发布了一篇解决这个问题的帖子,但它使用了一个构造用于viewmodel,它完全混淆了我,因为它为构造函数添加了一个“prototype.activate”方法,这完全是对我来说是新的(当我尝试使用它时不起作用)。
任何人都可以试着告诉我如何使用我的揭示模块模式使用Rob的示例如下所示?
我的观点模型:
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;
});
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;
});
编辑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;
});
答案 0 :(得分:5)
您必须了解返回单例视图模型和函数视图模型之间的根本区别。您还需要了解继承如何在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;
});
此viewmodel返回一个单例,并要求前一个作为依赖项:
define(['viewmodels/example'], function (Example) {
return {
exampleOne: new Example('This is a test!'),
exampleTwo: new Example('This is another test!')
};
});
由于'viewmodels / example'返回一个函数,我们必须使用new
关键字来实例化它(注意:如果你在视图中使用合成绑定,Durandal会为你做这个。)
exampleOne
和exampleTwo
都有独特的标题;但是,它们共享相同的activate()
方法。这是prototype
属性的优势。此策略可应用于您想要复制的视图,但共享相同的激活码,如模态对话框或小部件。
答案 1 :(得分:0)
好吧,在没有更多学习解决方案的情况下,我至少设法让它运转起来。我不得不删除ctor函数并使其成为普通页面变量。不得不删除所有对“self”的引用,就像在最后一个durandal事件中那样“this”不是窗口对象。
由于“compositionComplete未在我的viewmodel中触发,我使用”附加“代替。
工作代码:
define(['globalVar', 'services/datacontext', 'services/calccontext', "jquery", "knockout"], function (globalVar, datacontext, calcContext, $, ko) {
var chartConfig = {
data: ko.observableArray([]),
title: ko.observable(),
seriesColors: ko.observableArray([]),
series: ko.observableArray([]),
ticks: ko.observableArray([])
};
// subscriptions
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
chartConfig.data([
[300, 295, 290],
[320, 320, 320],
[260, 265, 260]
]);
chartConfig.title("Forecast net operating costs");
chartConfig.seriesColors(["#0026FF", "#FF6A00", "#606060"]);
chartConfig.series([
{ label: "Foo" },
{ label: "Bar" },
{ label: "Baz" }
]);
chartConfig.ticks(["Apr 13", "May 13", "Jun 13"]);
};
var activate = function () {
setChartVars();
return datacontext.newEntity(articleResults, "articleVersionResults");
};
var compositionComplete = function () {
//var self = this;
var c = chartConfig;
jqChart = $.jqplot("chart", c.data());
// example to change the data
setTimeout(function () {
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,
attached: compositionComplete,
calcAll: calcAll,
editArticleVersion: globalVar.editArticleVersion,
articleResults: articleResults
};
return vm;
});