2015-12-19 58 views
1

SOLUTIONAngularJS 1.4X如何扩展工厂对象

感谢赫格隆-Hegedus的下面回答。将它应用于我的实际代码并且效果很好。

// 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; 
} 

如何扩展下面的工厂对象。我使用lodash自动水合物工厂构造函数,它的伟大工程,但现在没有一个我原来的方法,例如执行isIcon()返回一个错误味精 - “isIcon不是一个函数”。我搜索了一个答案,但大多数构造函数示例在对象的末尾使用传统的return service;,这很好地工作,但这迫使我回到构建构造函数的更多手动方法。我觉得我失去了一些明显的东西。

使用AngularJS 1.4.8

工厂对象EXTEND

// 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)); 
    }; 
}); 

我试图延长IIEF工厂angular.extend(),但是这也不管用(下面的例子):

angular.extend(imageOfUnableToExtendFn, { 
    isIcon: function(img) { 
     return img.type === IMG_TYPE.ICON; 
    } 
}) 

更详细的A BOVE供参考用途

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); 

});

+0

尝试看看http://codereview.stackexchange.com/questions/40628/angularjs- extends-service – Whisher

+0

您是否想要创建Image类的子类,或者为现有类添加一些新功能?我没有看到如何使用ImageUnableToExtendFn。 –

+0

@Whisker谢谢,看着它和小孩的帖子。仍然无法得到它的工作。再次因为它返回一个立即执行的方法,而上面的帖子使用传统的带有子函数的对象返回。所以如果我在对象中添加一个构造函数,它不会立即执行。我可以在上面提到的传统方法中添加一个方法来保存构造函数,但是会发布对象的新实例。 – Nolan

回答

2

JavaScript中的子类化有点棘手。看看this SO post about javascript inheritance

基本上,这是你平时是怎么做到这一点,裹在角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); 
+0

万分感谢!我现在明白了...巨大的帮助 – Nolan

+0

顺便说一句,类似于你链接的例子有非常通用的JS OOP的例子,我得到,扩展,装饰,继承,但在AJS中应用它们似乎从未像现在这样做,坦率地说我的知识水平与AJS ...再次感谢! – Nolan