【问题标题】:Pass a viewmode edit/add to the durandaljs wizard将视图模式编辑/添加传递给 durandaljs 向导
【发布时间】:2013-09-18 02:11:03
【问题描述】:

https://github.com/dFiddle/dFiddle-2.0/blob/gh-pages/app/masterDetail/wizard/index.js

当我查看此向导时,我问自己如何将变量(例如处于向导的编辑或添加模式中的模式)传递给创建 step1、step2 和 step3 的 index.js。

我看不到我可以在哪里传递这些数据,因为 index.js 是保存所有步骤的主向导,它是由 durandal 动态创建的。

那么如何将数据传递给 index.js,以便我可以决定是运行 service.create() 还是 service.edit() 函数来获取不同的数据等...

更新

define(['durandal/app','plugins/dialog', 'knockout', 'services/dataservice', 'plugins/router', 'moment'], function (app, dialog, ko, dataservice, router, moment) {

    var SchoolyearDialog = function () {

        var self = this;
        self.activeScreen = ko.observable('viewmodels/SchoolyearBrowser'); // set the schoolyear browser as default module 

        app.on('startWizard').then(function (obj) {
            self.activeScreen(obj.moduleId);
        });       

        app.on('dialog:close').then(function (options) {
            dialog.close(self, options );
        });

        self.closeDialog = function () {            
            dialog.close(self, { isSuccess: false });
        }
    }
    SchoolyearDialog.show = function () {

        return dialog.show(new SchoolyearDialog());
    };

SchoolyearDialog 模块控制显示哪个屏幕。 SchoolyearDialog 订阅了 startWizard 事件。按下 createWizard 按钮会触发 startWizard 事件。还有一个 editWizard 按钮可以触发另一个事件,例如 startWizardEdit。 activeScreen 设置为默认模块 ID:'viewmodels/SchoolyearBrowser' 或 模块 id: 'viewmodels/SchoolyearWizard' 加载向导

是否有可能以某种方式向 activeScreen 属性传递一个值 (viewMode) 并在保存步骤的向导模块中检索它?

【问题讨论】:

  • 谁在控制初始向导模式?该示例可能并不理想,因为它 a) 返回一个单例,而您可能正在寻找一个构造函数,并且 b) 它是通过子路由器激活的,这限制了您可以传递给 activate 函数的内容。
  • 我已经用更多信息更新了我的初始化问题。谢谢雷纳 :)
  • 非常好的用例,所以我继续创建了一个新示例。
  • “相当好的用例......”因为它的真实生活样本 ;-) 生活写出最好的故事嘿嘿。

标签: durandal


【解决方案1】:

我稍微更新了初始示例,使其更适合此用例。 在 index.js 中,您必须创建向导的实例,然后将其传递给 activeScreen 可观察对象(如果您需要完整的 Durandal 事件生命周期,也可以在此处选择激活器)。

看看http://dfiddle.github.io/dFiddle-2.0/#master-detail/wizard2 看看它的实际效果。

Index.js https://github.com/dFiddle/dFiddle-2.0/blob/gh-pages/app/masterDetail/wizard2/index.js

define(['durandal/activator', 'knockout', './wizard'], function( activator, ko, Wizard ) {

    var ctor = function() {
        this.activeScreen = ko.observable();
    };

    ctor.prototype.activate = function( wizId ) {

        // Get wizard data based on wizId from the backend
        var json =
            {"id": "wizard001", "mode": "create", "steps": [
                {"id": "s001", "name": "step one", "props": {"prop1": "a", "prop2": "b"}},
                {"id": "s002", "name": "step twoe", "props": {"prop3": "a", "prop4": "b"}},
                {"id": "s003", "name": "step three", "props": {"prop5": "a", "prop6": "b"}},
                {"id": "s004", "name": "step four", "props": {"prop7": "a", "prop8": "b"}},
                {"id": "s005", "name": "step five", "props": {"prop9": "a", "prop10": "b"}}
            ]};

        this.activeScreen(new Wizard(json));
    };

    return ctor;

});

wizard.js https://github.com/dFiddle/dFiddle-2.0/blob/gh-pages/app/masterDetail/wizard2/wizard.js

define(['durandal/activator', './step', 'knockout'], function( activator, Step, ko ) {

    var ctor = function( options ) {

        ...

        this.init(this._options);

        this.stepsLength = ko.computed(function() {
            return this.steps().length;
        }, this);

        this.hasPrevious = ko.computed(function() {
            return this.step() > 0;
        }, this);

        this.hasNext = ko.computed(function() {
            return (this.step() < this.stepsLength() - 1);
        }, this);

    };

    ...

    ctor.prototype.init = function( options ) {
        var json = options;

        this.id(json.id);
        this.mode(json.mode);

        this.steps(createSteps(options.steps));

        function createSteps ( steps ) {
            var result = [];
            $.each(steps, function( idx, obj ) {
                result.push(new Step(obj));
            });
            return result;
        }

        this.activateStep();

    };

    return ctor;
});

step.js https://github.com/dFiddle/dFiddle-2.0/blob/gh-pages/app/masterDetail/wizard2/step.js

define(['knockout'], function( ko ) {

    var Property = function( id, val ) {
        this.id = id,
            this.val = ko.observable(val);
    };

    var ctor = function( options ) {
        this._options = options || {};
        this.id = ko.observable();
        this.name = ko.observable();
        this.props = ko.observableArray([]);

        this.init(this._options)
    };

    ctor.prototype.init = function( options ) {

        this.id(options.id || '');
        this.name(options.name || '');

        this.props(createProperties(options.props));

        function createProperties (props) {
            var result = [];
            $.each(props, function( prop, val ) {
                result.push(new Property(prop, val));
            });

            return result;
        }

    };
    return ctor;

});

随意分叉,我正在接受拉取请求;-)

【讨论】:

  • 我有点困惑,为什么您将 wizId 传递给 activate 函数,因为您从未读取过变量?如果我理解正确,我只需要说:this.activeScreen(new Wizard('edit'));或 this.activeScreen(new Wizard('create'));取决于按下哪个按钮编辑/创建然后触发事件......对吗?
  • 好的,我只是按照我之前的要求做了,它有效。在我的向导中,我可以区分是执行创建还是编辑服务调用。再次感谢雷纳。
  • 这是一个例子;-)。有init 函数的原因是您现在可以在构造函数中运行init,或者如果您通过activate 使用激活器。上面的示例将允许您通过进行异步调用从后端读取向导状态。在您的情况下,您只对editcreate这两个州感兴趣,所以new Wizard('create|edit')就是所需要的......至少现在是这样。
  • "从后端读取向导状态..." 我对此感到困惑。当有人想从后端读取向导状态时,您是否有这样的场景?在我们的上下文中,后端对您意味着什么? clientDataService.js 还是在服务器端?
  • 考虑一个向导工厂,它允许 a) 创建多个向导,每个向导都有自己的步骤/属性和 b) 将向导状态(到目前为止已填写的步骤/属性)保存/重新加载到服务器。如前所述,这是一个人为的示例,其中包含不适用于您的场景的部分。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-13
  • 1970-01-01
  • 1970-01-01
  • 2012-05-17
  • 1970-01-01
  • 1970-01-01
  • 2020-04-13
相关资源
最近更新 更多