Javascript AngularJS 1.4x如何扩展factory对象

Javascript AngularJS 1.4x如何扩展factory对象,javascript,angularjs,Javascript,Angularjs,解决方案 感谢黑格·黑格杜斯下面的答案。将它应用到我的实际代码中,效果非常好 // NOTE : called from another service, but removed function wrap around and angular module setup for brevity sake // article is serverObject var articleInstance = new Article(article); console.log(articleInstanc

解决方案

感谢黑格·黑格杜斯下面的答案。将它应用到我的实际代码中,效果非常好

// NOTE : called from another service, but removed function wrap around and angular module setup for brevity sake
// article is serverObject
var articleInstance = new Article(article);
console.log(articleInstance instanceof Article)
// true
console.log(articleInstance.isProduct(article))
// true (in my case)

/*
* Create the constructor from server article object using lodash
*/
ArticleConstructor.$inject = [];
function ArticleConstructor() {
    return function(data) {
        var keys = ['app_id', 'body', 'headline', 'object_type', 'url', 'status'
        ];
        _.assign(this, _.pick(data, keys));
    };
}

/*
* Extend the iief constuctor - ArticleConstruct
*/
Article.$inject = ['ArticleConstructor'];
function Article(ArticleConstructor) {

    function ArticleExtended(data) {
        ArticleConstructor.call(this, data);
    }

    //  create the new Article object with the ArticleConstructor prototype object and properties
    ArticleExtended.prototype = Object.create(ArticleConstructor.prototype);

    // Article inherits a constructor property from its prototype i.e. ArticleConstructor
    ArticleExtended.prototype.constructor = ArticleExtended;

    ArticleExtended.prototype.isProduct = function () {
        return this.object_type == 3;
    };

    ArticleExtended.prototype.hasImage = function () {
        return _.has(this, 'image');
    };

    return ArticleExtended;
}
如何扩展下面的factory对象。我正在使用lodash来自动生成工厂构造函数,这非常有效,但现在没有一个原始方法执行,例如,
isIcon()
返回错误消息-“isIcon不是函数”。我一直在寻找答案,但大多数构造函数示例都使用传统的
返回服务位于对象的末尾,这很好,但随后迫使我返回到更手动的方法来构建构造函数。我觉得我错过了一些明显的东西

使用AngularJS 1.4.8

要扩展的工厂对象

// AJS factory - the problem child
ImageUnableToExtendFn.$inject = ['IMG_TYPE'];
function ImageUnableToExtendFn(IMG_TYPE) {

  Image.prototype.isIcon = function (img) {
    return img.type === IMG_TYPE.ICON;
  };

 return function(data) {
    var keys = ['id', 'src', 'alt', 'type'];
       _.assign(this, _.pick(data, keys));
    };
});
我已尝试使用angular.extend()扩展IIEF工厂,但这也不起作用(下面的示例):

以上内容更详细,仅供参考

define([
   'angular',
   'lodash'

], function(angular, _) {
'use strict';

ImageService.$inject = ['ImageClassicFn', 'ImageUnableToExtendFn'];
function ImageService(ImageClassicFn, ImageUnableToExtendFn) {

    var imageService = {
        images: null,

        createInstance: function(serverImageObject) {
            var self = this,
                imageOfClassicFn,
                imageOfUnableToExtendFn,
                isIcon,

            if (angular.isDefined(serverImageObject)) {

                imageOfClassicFn = new ImageClassicFn();
                isIcon = imageOfClassicFn.isIcon(serverImageObject);
                console.log('IS ICON', isIcon);
                // >  true of false 

                imageOfUnableToExtendFn = new ImageUnableToExtendFn(serverImageObject);
                // result is a hydrated instance of ImageClassicFn with mapped keys using lodash
                isIcon = imageOfClassicFn.isIcon(serverImageObject);
                // ERROR - isIcon is not a function 

                // Attempting to extend manually fails silently 
                angular.extend(imageOfUnableToExtendFn, {
                    isIcon: function(img) {
                        return img.type === IMG_TYPE.ICON;
                    }
                })

                isIcon = imageOfClassicFn.isIcon(serverImageObject);
                // SAME ERROR - isIcon is not a function 
            }
        }
    };

    return imageService;
}

ImageClassicFn.$inject = ['IMG_TYPE'];
function Image(IMG_TYPE) {

  function Image(id, src, alt, type) {
    this.id = id;
    this.src = src;
    this.alt = alt;
    this.type = type;
  }

  Image.prototype.isIcon = function (img) {
    return img.type === IMG_TYPE.ICON;
  };

    return Image;
});

ImageUnableToExtendFn.$inject = ['IMG_TYPE'];
function Image(IMG_TYPE) {

  Image.prototype.isIcon = function (img) {
    return img.type === IMG_TYPE.ICON;
  };

return function(data) {
    var keys = ['id', 'src', 'alt', 'type'];
       _.assign(this, _.pick(data, keys));
    };
});


return angular.module('content.images', [

    ])
     .constant("IMG_TYPE", {
        "ICON": 1,
    })
    .factory('ImageClassicFn', ImageClassicFn)
    .factory('ImageUnableToExtendFn', ImageUnableToExtendFn)
    .service('ImageService', ImageService);

}))

javascript中的子类化有点棘手。看一看

基本上,这就是通常的做法,用angular 1.x模块包装:

ImageClassicFactory.$inject = ['IMG_TYPE'];
function ImageClassicFactory(IMG_TYPE) {

  function ImageClassic(id, src, alt, type) {
    this.id = id;
    this.src = src;
    this.alt = alt;
    this.type = type;
  }

  ImageClassic.prototype.isIcon = function (img) {
    return img.type === IMG_TYPE.ICON;
  };

  return ImageClassic;
});
module.factory('ImageClassic', ImageClassicFactory);



ImageExtendedFactory.$inject = ['IMG_TYPE', 'ImageClassic'];
function ImageExtendedFactory(IMG_TYPE, ImageClassic) {

  function ImageExtended(id, src, alt, type) {
      ImageClassic.call(this, id, src, alt, type);
  }
  ImageExtended.prototype = Object.create(ImageClassic.prototype);
  ImageExtended.prototype.constructor = ImageExtended;

  ImageExtended.prototype.isIcon = function (img) {
    return img.type === IMG_TYPE.ICON;
  };

  return ImageExtended;
});

module.factory('ImageExtended', ImageExtendedFactory);

试着看一看您是想创建
Image
类的子类,还是想向现有类添加一些新功能?我不知道如何使用
ImageUnableToExtendFn
。@Whisker谢谢,看了它和孩子们的帖子。仍然无法让它工作。同样是因为它返回一个立即执行的方法,而上面的post使用了带有子函数的对象的传统返回。所以,如果我在对象中添加构造函数,它将不会立即执行。我可以在上面提到的传统方法中添加一个方法,使构造函数水合物化,但这是在对象的新实例之后添加的。@hege_hegedus抱歉,我在添加到标记时一定把它搞砸了。在我的实际代码中,我是对的,但不知怎的。。。迷失在翻译中。。英雄联盟除此之外,问题仍然存在。如果工厂中有一个立即执行的函数,它将丢失原始属性。我理解为什么它会返回一个立即执行的函数,而不是一个包含函数的对象,但我不知道最好的方法。顺便说一句,与您链接的示例类似,我得到了一些非常通用的JS OOP示例,扩展、装饰、继承,但在AJS中应用它们似乎永远不会有同样的效果,坦率地说,这是我的知识水平与AJS相比。。。再次感谢!
ImageClassicFactory.$inject = ['IMG_TYPE'];
function ImageClassicFactory(IMG_TYPE) {

  function ImageClassic(id, src, alt, type) {
    this.id = id;
    this.src = src;
    this.alt = alt;
    this.type = type;
  }

  ImageClassic.prototype.isIcon = function (img) {
    return img.type === IMG_TYPE.ICON;
  };

  return ImageClassic;
});
module.factory('ImageClassic', ImageClassicFactory);



ImageExtendedFactory.$inject = ['IMG_TYPE', 'ImageClassic'];
function ImageExtendedFactory(IMG_TYPE, ImageClassic) {

  function ImageExtended(id, src, alt, type) {
      ImageClassic.call(this, id, src, alt, type);
  }
  ImageExtended.prototype = Object.create(ImageClassic.prototype);
  ImageExtended.prototype.constructor = ImageExtended;

  ImageExtended.prototype.isIcon = function (img) {
    return img.type === IMG_TYPE.ICON;
  };

  return ImageExtended;
});

module.factory('ImageExtended', ImageExtendedFactory);