角度工厂/服务的单独实例

时间:2014-03-10 15:59:34

标签: javascript angularjs

我有一个工厂函数,它有一些数据和一些操作它的函数。此数据在应用程序中多次使用,在某些点上数据在页面上,然后也以模态打开 - 操作模式中的数据更改后台页面中的数据。创建单独的数据实例的最“角度方式”是什么?

更新

工厂:

factory('filterFactory', [function () {


return {
    getGroups: function(term){
        // TODO: get terms groups with $http
        if(term){
            // get terms
        }
        else {
            return this.terms;
        }
    },
    addGroup: function(group){
        for (var term in this.terms) {
            if(this.terms[term].name === group){
                this.terms[term].included = true;
            }
        }
    },
    removeGroup: function(group){
        for (var term in this.terms) {
            if(this.terms[term].name === group){
                this.terms[term].included = false;
            }
        }
    },
    selectGroup : function(group){
        for (var term in this.terms) {
            if(this.terms[term].name === group){
                this.terms[term].included = true;
            } else {
                this.terms[term].included = false;
            }
        }
    },
    setAll : function(value){
        for (var term in this.terms) {
            this.terms[term].included = value;
        }
    },

    isCollapsed: true,

    terms: {
        people: {
            included: false,
            name: 'person',
        },
        organizations: {
            included: false,
            name: 'organization',
        },
        ...
    }

};

}])。

尝试实施:

    $scope.newTermMeta.type = filterFactory;

var temp = filterFactory;
$scope.newTermMeta.type = temp.terms;

$scope.newTermMeta.type = filterFactory.getGroups();

var temp = filterFactory;
$scope.newTermMeta.type = temp.terms;

$scope.newTermMeta.type = Object.create(filterFactory.getGroups());

注意:上述实现都没有创建一个孤立的实例。

模板代码:

<div class="modal-body">

    <form>
        <label> 
            <h2>{{newTermMeta.name}}</h2>
        </label>
        <br>
        <span>Add your term to relevant term groups:</span>
        <br>
        <div class="well well-sm col-sm-8">
            <button ng-repeat="group in newTermMeta.type" btn-checkbox class="btn btn-sm btn-default margin5" type="button" ng-model="group.included">{{group.name}}</button>
        </div>
        <br>
        <span>Optional:</span>
        <br>
        <label> Enter a concise (at most one sentence) definition for this term:</label>
        <input class="form-control width80p" type="text" ng-model="newTermMeta.definition">
    </form>
</div>

1 个答案:

答案 0 :(得分:1)

工厂对象是一个共享实例,因此您在该工厂对象中更改的任何内容都将针对使用它的每个人进行更改。

工厂是正确的做法,但听起来你想将它封装在不同的范围内。使用Angular相当容易,因为所有控制器都有自己的范围,指令也可以选择拥有自己的范围。假设您在控制器中显示它,您可以执行以下操作:

myapp.controller('OtherCtrl', [ 'MyFactory', '$scope', function(MyFactory,$scope) {

  // create a defensive copy of the factory object by creating a new object with the wrapped object as its prototype chain, anything can then access the data but changing the properties change only on $scope.theObject directly
  $scope.theObject = Object.create(MyFactory.getTheObject());

 // alternatively, copy the relevant properties into our scope, it's protected but you won't be updated when the factory object changes unless you also specify a $watch statement
 var obj = MyFactory.getTheObject();
 $scope.name = obj.name;

}]);

更新:警告

使用Object.create()防御性复制机制时的一个警告是,它只会对您修改的属性进行JSON字符串化。如果您打算修改属性然后将整个对象提交回服务器,它将无法工作。它确实适用于只读属性,或仅用于序列化已修改的属性。 Angular将在没有$ watch的情况下更新未修改属性的值,因为它仍然可以通过原型链检测更改。

显示JSON.stringify与原型链值之间差异的小提琴在这里http://jsfiddle.net/XXdqv/