如何使用服务跨Angular控制器持久化对象实例?

时间:2015-06-08 14:44:21

标签: javascript angularjs

我正在尝试在Angular中的多个控制器和指令之间传递“用户模型”实例。我的模型看起来像这样:

var userFactory = function (addressFactory) {
    var User = function () {
        BillingAddress = addressFactory.createAddress();
        ShippingAddress = addressFactory.createAddress();
        FirstName = '';
    }

    return {
        create: function(){return new User()}
    }
}


var userModel = function (userFactory) {

    var model = userFactory.create();

    return {
        model: model
    }
}
app.factory('addressFactory', ['securedHttp', 'utility', addressFactory]);
app.factory('userFactory', ['addressFactory', userFactory]);

userModel.model将用于绑定Angular表单,包括多个控制器。我希望所有控制器中的更改将其更改反映回此实例。

我希望所有服务都能够引用此userModel.model并获取对模型所做的最新更改。

 var MyController1 = function ($scope, userModel) {
   $scope.user = userModel;
   userModel.model.FirstName = "blahblah";

}
   var MyDirectiveController2 = function ($scope, userModel) {
        //EXPECT:
        userModel.model.FirstName == "blahblah";
}

var myOtherService = function(userModel){
//EXPECT:
userModel.model.FirstName == "blahblah";
}

这不起作用。我的理解是服务是单身,但我无法改变模型上的数据,并且反映了不同的背景。

有关正确方法的任何建议吗?我可以共享范围或将范围变量传递给每个控制器,但这似乎是一种传递已经作为服务存在的依赖关系的混乱方式。

2 个答案:

答案 0 :(得分:1)

是的,服务是单例,但是您的userFactory不会为您的模型对象利用setter / getter。

var userFactory = function(addressFactory) {

    var model = null;
    var create = function() {
        var self = this;
        self.BillingAddress = addressFactory.createAddress();
        self.ShippingAddress = addressFactory.createAddress();
        self.FirstName = '';
    };

    var setModel = function(data) {
        model = data;
    };

    var getModel = function() {
        return model;
    };

    return {
        create : create,
        getModel : getModel,
        setModel : setModel
    }

}

答案 1 :(得分:1)

我对你的代码感到有点困惑。您是否尝试将数据绑定到userFactory.billingAddress等或userModel.model? 一个大问题是你设置self.model = userFactory.create()但userFactory.create没有返回任何东西。所以基本上,user.model将是未定义的。

我不知道您的确切用例,因此无法提供最佳解决方案。在大多数情况下,用户模型将负责仅存储用户数据,用户工厂将负责仅创建用户,并且通常将从某个控制器/指令调用。一个例子是,从登录控制器,我将调用loginServive,它将从后端api获取成功登录的用户详细信息,然后将用户详细信息存储在usermodel中。

在您的示例中,我不会从usermodel调用userFactory.create。如果要从其他工厂或控制器创建模型,则将从该工厂/控制器调用create方法。或者,我只是在userFactory中初始化userModel。

var userFactory = function (addressFactory, userModel) {
    var create = function () {
        userModel.model.BillingAddress = addressFactory.createAddress();
        userModel.model.ShippingAddress = addressFactory.createAddress();
        userModel.model.FirstName = '';
    }

    // if you want to expose create method to public
    return {
        create: create
    }
}

var userModel = function () {
    var model = {
      BillingAddress: {},
      ShippingAddress: {},
      FirstName = ""
    };

    return {
        model: model
    }
}

app.factory('userFactory', ['addressFactory', 'userModel', userFactory]);
app.factory('userModel', [userModel]);

编辑:我根据您在代码中尝试实现的内容创建了一个plunker。见here。我添加了几个控制器并将userModel注入其中。我还演示了如何在2个控制器和设置双向绑定之间共享数据,以便持久保存数据。希望有所帮助。

您的代码中存在一些问题 -

  1. 在功能用户中,您必须将地址属性附加到此处,否则它将不会附加到创建的对象。在您的情况下,FirstName等将附加到窗口对象,而不是附加到用户实例。

  2. 您需要将userModel定义为要注入另一个控制器/服务等的工厂/服务,但我想您已经知道了。

  3. 我仍然认为userModel不是创建模型的地方。如果你想在app init上创建模型,那么就在userFactory中进行,然后从那里将它保存在userModel中,正如我在上面的代码示例中所示。