将JS单例转换为实例/ ctor的策略

时间:2015-04-17 15:03:35

标签: javascript durandal

以下是Durandal入门套件的示例,该套件返回单件。我很好奇最简单的方法是将其转换为实例,最好不要完全改变语法。

define(['plugins/http', 'durandal/app', 'knockout', 'lodash'], function (http, app, ko, _) {
                var displayName = 'Flickr',
                                images = ko.observableArray([]),
                                activate = function () {
                                                //the router's activator calls this function and waits for it to complete before proceeding
                                                if (this.images().length > 0) {
                                                                return;
                                                }

                                                var that = this;
                                                return http.jsonp('http://api.flickr.com/services/feeds/photos_public.gne', { tags: 'mount ranier', tagmode: 'any', format: 'json' }, 'jsoncallback').then(function(response) {
                                                                that.images(response.items);
                                                });
                                },
                                select = function(item) {
                                                //the app model allows easy display of modal dialogs by passing a view model
                                                //views are usually located by convention, but you an specify it as well with viewUrl
                                                item.viewUrl = 'views/detail';
                                                app.showDialog(item);
                                },
                                somePrivate = function() { return ‘blah’; },
                                canDeactivate = function () {
                                                //the router's activator calls this function to see if it can leave the screen
                                                return app.showMessage('Are you sure you want to leave this page?', 'Navigate', ['Yes', 'No']);
                                };

                return {
                                displayName: displayName,
                                images: images,
                                activate: activate,
                                select: select,
                                canDeactivate: canDeactivate
                };
});

这有效,但添加“这个”是一种痛苦。无处不在,我也失去了公开/私人的区别:

define(['plugins/http', 'durandal/app', 'knockout', 'lodash'], function (http, app, ko, _) {
                var ctor = function() {
                                this.displayName = 'Flickr';
                                this.images = ko.observableArray([]);
                                this.activate = function () {
                                                //the router's activator calls this function and waits for it to complete before proceeding
                                                if (this.images().length > 0) {
                                                                return;
                                                }

                                                var that = this;
                                                return http.jsonp('http://api.flickr.com/services/feeds/photos_public.gne', { tags: 'mount ranier', tagmode: 'any', format: 'json' }, 'jsoncallback').then(function(response) {
                                                                that.images(response.items);
                                                });
                                };
                                this.select = function(item) {
                                                //the app model allows easy display of modal dialogs by passing a view model
                                                //views are usually located by convention, but you an specify it as well with viewUrl
                                                item.viewUrl = 'views/detail';
                                                app.showDialog(item);
                                };
                                this.canDeactivate = function () {
                                                //the router's activator calls this function to see if it can leave the screen
                                                return app.showMessage('Are you sure you want to leave this page?', 'Navigate', ['Yes', 'No']);
                                };
                };

    return ctor;
});

我想像下面这样的工作 - 任何提示?

define(['plugins/http', 'durandal/app', 'knockout', 'lodash'], function (http, app, ko, _) {
    var ctor = function() {
        var displayName = 'Flickr',
            images = ko.observableArray([]),
            activate = function () {
                //the router's activator calls this function and waits for it to complete before proceeding
                if (this.images().length > 0) {
                    return;
                }

                var that = this;
                return http.jsonp('http://api.flickr.com/services/feeds/photos_public.gne', { tags: 'mount ranier', tagmode: 'any', format: 'json' }, 'jsoncallback').then(function(response) {
                    that.images(response.items);
                });
            },
            select = function(item) {
                //the app model allows easy display of modal dialogs by passing a view model
                //views are usually located by convention, but you an specify it as well with viewUrl
                item.viewUrl = 'views/detail';
                app.showDialog(item);
            },
            canDeactivate = function () {
                //the router's activator calls this function to see if it can leave the screen
                return app.showMessage('Are you sure you want to leave this page?', 'Navigate', ['Yes', 'No']);
            };

        return {
            displayName: displayName,
            images: images,
            activate: activate,
            select: select,
            canDeactivate: canDeactivate
        };
    };

    return _.bind(ctor, this);
});

我也在vars之前和之后在ctor内部尝试了_.bindAll。

2 个答案:

答案 0 :(得分:0)

你有没有试过让ctor成为IIFE?像这样:

define(['plugins/http', 'durandal/app', 'knockout', 'lodash'], function (http, app, ko, _) {
var ctor = (function() {
    var displayName = 'Flickr',
        images = ko.observableArray([]),
        activate = function () {
            //the router's activator calls this function and waits for it to complete before proceeding
            if (this.images().length > 0) {
                return;
            }

            var that = this;
            return http.jsonp('http://api.flickr.com/services/feeds/photos_public.gne', { tags: 'mount ranier', tagmode: 'any', format: 'json' }, 'jsoncallback').then(function(response) {
                that.images(response.items);
            });
        },
        select = function(item) {
            //the app model allows easy display of modal dialogs by passing a view model
            //views are usually located by convention, but you an specify it as well with viewUrl
            item.viewUrl = 'views/detail';
            app.showDialog(item);
        },
        canDeactivate = function () {
            //the router's activator calls this function to see if it can leave the screen
            return app.showMessage('Are you sure you want to leave this page?', 'Navigate', ['Yes', 'No']);
        };

    return {
        displayName: displayName,
        images: images,
        activate: activate,
        select: select,
        canDeactivate: canDeactivate
    };
}());

return ctor;

});

答案 1 :(得分:0)

define(['plugins/http', 'durandal/app', 'knockout', 'lodash'], function (http, app, ko, _) {
    var ctor = function() {
        var displayName = 'Flickr',
        images = ko.observableArray([]),
        activate = function () {
            //the router's activator calls this function and waits for it to complete before proceeding
            if (images().length > 0) {
                return;
            }

            var that = this;
            return http.jsonp('http://api.flickr.com/services/feeds/photos_public.gne', { tags: 'mount ranier', tagmode: 'any', format: 'json' }, 'jsoncallback').then(function(response) {
                that.images(response.items);
            });
        },
        select = function(item) {
            //the app model allows easy display of modal dialogs by passing a view model
            //views are usually located by convention, but you an specify it as well with viewUrl
            item.viewUrl = 'views/detail';
            app.showDialog(item);
        },
        canDeactivate = function () {
            //the router's activator calls this function to see if it can leave the screen
            return app.showMessage('Are you sure you want to leave this page?', 'Navigate', ['Yes', 'No']);
        };

        _.extend(this, {
            displayName: displayName,
            images: images,
            activate: activate,
            select: select,
            canDeactivate: canDeactivate
        });
    };

    return ctor;
});

这似乎与我正在寻找的非常接近,并且几乎是直接翻译。