激活方法和ctor.prototype.activate之间的Durandal和Knockout区别?

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)

Bre*_*ett 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;
});
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会为你做这个).

双方exampleOneexampleTwo具有独特的称号; 但是,他们有相同的activate()方法.这是该prototype物业的优势.此策略可应用于您希望重复的视图,但共享相同的激活代码,如模式​​对话框或小部件.