0

I am trying to implement a baseEntity class for entities such as user and groups but isFavourite property can not read the correct Id() from persistanceId() when it is in baseEntity. (type and Id() come out as undefined and surprisingly type has the correct value in confirmDelete)

define(["knockout"], function (ko) {
    var app = require('durandal/app');
    ko.baseEntity = function (data) {
        var self = this;
        self.Id = ko.observable();
        self.confirmDelete = function () {
            var result;
            app.showMessage(
                'Are you sure you want to delete the ' + self.type + ' ' + self.Name() + '?',
                'Deleting ' + self.type, ['Yes', 'No']).then(
                function (dialogResult) {
                    dialogResult === "Yes" ? result = true : result = false;
                });
            return result;
        };
        self.persistanceId = function () {
            return self.type + '-' + self.Id() + "-IsFavourite";
        };
        self.isFavourite = ko.observable(false).extend({
            persist: self.persistanceId()
        });
        self.toggleFavourite = function () {
            self.isFavourite(!self.isFavourite());
        };
    }
    return {
        model: ko.baseEntity
    }
});

but if isFavourite instead of being here in baseEntity it is for example part of group then it works fine.

define(["knockout", "models/baseentity"], function (ko, baseEntity) {
    var
    model = function (data) {
        var self = this;
        baseEntity.model.call(self);
        self.type = 'group';
        self.Id(data.Id);
        self.Name = ko.observable(data.Name);
        self.Description = ko.observable(data.Description);
        self.Members = ko.observableArray(data.Members);
        self.isFavourite = ko.observable(false).extend({
            persist: self.persistanceId()
        });
    }
    return {
        model: model
    }
});

Could someone explain to me what is going on here and how can I move my base property back in my baseentity as it is shared across various other things too.

4

3 回答 3

2

我不是 javascript 大师,但我希望将模型层次结构的继承与淘汰赛分离——如果你实现它,模型的行为是否符合预期?

于 2013-10-02T17:25:44.963 回答
1

我不明白你为什么要修改淘汰对象本身?我相信 Dave Lowe 建议您仅在 JavaScript 中执行此操作是正确的。模型上的属性,在它们影响您的视图的范围内,应该是可观察的,但您的模型不需要附加到淘汰赛。

另外,考虑花一些时间在http://objectplayground.com上,它有一个关于学习面向对象 JavaScript 的很棒的教程。您的范例应该看起来更像这样:

function Model(obj) {

    this.attribute = obj.attribute;

    this.observable = ko.observable(obj.observable);

    this.localFunction = function(val) {
        if (obj.attr == true) this.observable(val);
    };
}

Model.prototype.globalFunction = function(data) {
    this.observable(data);
};

请特别注意,如果方法依赖于局部变量,即传递给构造函数的参数,则需要在构造函数中定义它。否则,您应该在原型上定义方法。

这种范式与 durandal 中的 require 配合得非常好,因为您可以执行以下操作:

define(function(require) {
    var Model = require('model');
    var object = new Model({});
})
于 2013-10-03T14:37:23.023 回答
0

好的,显然在 ko 中执行此子类业务的更简单方法是使用 ko 本身。谁曾想到 :)

所以现在我将我的基本模型定义为:

define(["knockout"], function (ko) {
    var app = require('durandal/app');
    ko.baseEntity = function (type, data) {
        var self = this;
        self.Id = ko.observable(data.Id);
        self.Type = ko.observable(type);
        self.Name = ko.observable();
        self.persistanceId = ko.computed(function () {
            return self.Type() + '-' + self.Id() + "-IsFavourite";
        });
        self.isFavourite = ko.observable(false).extend({
            persist: self.persistanceId()
        });
        self.toggleFavourite = function () {
            self.isFavourite(!self.isFavourite());
        };
        self.confirmDelete = function () {
            var result;
            app.showMessage('Are you sure you want to delete the ' + self.Type() + ' ' + self.Name() + '?', 'Deleting ' + self.Type(), ['Yes', 'No'])
                .then(function (dialogResult) {
                    dialogResult === "Yes" ? result = true : result = false;
                });
            return result;
        };
    }
    return {
        model: ko.baseEntity
    }
});

如您所见,我现在添加了传递给具体实现的相同数据参数。这是可能的,因为稍后我将使用它ko.utils.extend来创建它的一个实例并扩展它:

define(["knockout", "models/baseentity", "config"], function (ko, baseEntity, config) {
    var
    model = function (data) {
        var self = this;
        ko.utils.extend(self, new baseEntity.model(config.subClassTypes.user, data));
        self.Id(data.Id);
        self.FirstName = ko.observable(data.FirstName);
        self.LastName = ko.observable(data.LastName);
        self.JobTitle = ko.observable(data.JobTitle);
        self.UserLevel = ko.observable(data.UserLevel);
        self.Groups = ko.observableArray(data.Groups);
        self.ImageUrl = data.ImageUrl;
        self.Name(self.FirstName() + ' ' + self.LastName());
    }
    return {
        model: model
    }
});

另一个子类示例:

define(["knockout", "models/baseentity", "config"], function (ko, baseEntity, config) {
    var
    model = function (data) {
        var self = this;
        ko.utils.extend(self, new baseEntity.model(config.subClassTypes.group, data));
        self.Id(data.Id);
        self.Name(data.Name);
        self.Description = ko.observable(data.Description);
        self.Members = ko.observableArray(data.Members);       
    }
    return {
        model: model
    }
});

通过这种方式,我设法将我的方法转移到了基础上,并且效果很好。我讨厌回答我自己的问题,所以等待有人添加一些我可以打勾的有价值的好答案。

于 2013-10-03T09:11:45.407 回答