在控制器angular js之间共享数据

share data between controllers angular js

本文关键字:共享 数据 之间 js 控制器 angular      更新时间:2023-09-26

为什么FirstSecond控制器中的$scope.items仍然具有值First为什么在调用Load()函数后不更改为值From controller

家庭控制器:

namespace MvcApplication6.Controllers
{
    public class HomeController : Controller
    {
        //
        // GET: /Home/
        public ActionResult Index()
        {
            return View();
        }
        public JsonResult GetData()
        {
            string data = "From controller";
            return Json(data, JsonRequestBehavior.AllowGet);
        }
    }
}

索引.cshtml

@{
    ViewBag.Title = "Index";
}
<h2>Index</h2>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap-theme.min.css" rel="stylesheet" />
<script src="~/Scripts/jquery-1.9.1.min.js"></script>
<script src="~/Scripts/angular.js"></script>
<script src="~/Scripts/MyScript/Custom.js"></script>
<script src="~/Scripts/angular-animate/angular-animate.min.js"></script>
<script src="~/Scripts/angular-ui/ui-bootstrap.min.js"></script>
<script src="~/Scripts/angular-ui/ui-bootstrap-tpls.min.js"></script>
<div ng-controller="LoadData" id="data">
</div>
<div ng-controller="First">
    {{items}}
</div>
<div ng-controller="Second">
    {{items}}
</div>
<script>
    $(document).ready(function () {
        angular.element(document.getElementById('data')).scope().Load();
    });
</script>

自定义.js

var app = angular.module('MyApp', ['ngAnimate',  'ui.bootstrap']);
app.controller('First', function ($scope, sharedProperties) {
    $scope.items = sharedProperties.getProperty();
    console.log("First controller",sharedProperties.getProperty());
});
app.controller('Second', function ($scope, sharedProperties) {
    $scope.items = sharedProperties.getProperty();
    console.log("Second controller", sharedProperties.getProperty());
});
app.controller('LoadData', function ($scope,$http, sharedProperties) {
    $scope.Load = function () {
        $http({ method: 'GET', url: '/Home/GetData' }).
   success(function (data, status, headers, config) {
       sharedProperties.setProperty(data);
       console.log('Loaded data',data);
   }).
   error(function (data, status, headers, config) {
       alert('error');
   });
}
}
);
app.service('sharedProperties', function () {
        var property = 'First';
        return {
            getProperty: function () {
                return property;
            },
            setProperty: function (value) {
                property = value;
            }
        };
    });

问题是,在First和Second控制器中,变量$scope.items都是在加载控制器时初始化的。在那一刻之后,他们再也没有改变。

此处的执行顺序如下:

  1. 初始化控制器"First"及其变量$scope.items
  2. 初始化控制器"Second"及其变量$scope.items
  3. 会调用来自$http的回调,但在任何一个控制器上都不会更新$scope.items的值

作为一种可能的解决方案,您可以实现一个简单的回调机制(标准的观察者模式)。例如:

app.service('sharedProperties', function () {
        var property = 'First';
        var callBacks = [];
        return {
            getProperty: function () {
                return property;
            },
            setProperty: function (value) {
                property = value;
                callBacks.forEach(function(callBack) { 
                  callBack(value);
                });
            },
            registerCallback: function(callBack) {
              callBacks.push(callBack);
            }            
        };
    }); 

然后你让你的控制器注册他们的回调:

app.controller('First', function ($scope, sharedProperties) {
    sharedProperties.registerCallback(function(data) {
      $scope.items = data;
    });
});

或者,您可以使用Angular事件在控制器之间进行通信。

原因是您使用的是字符串。这意味着当你打电话时:

$scope.items = sharedProperties.getProperty();

您正在获取字符串的副本。要在控制器之间共享数据,您可以如下修改控制器:

html:

...
<div ng-controller="First">
    {{items.getProperty()}}
</div>
...

js:

...
app.controller('First', function ($scope, sharedProperties) {
    $scope.items = sharedProperties;
});
...

或修改您的服务:

app.service('sharedProperties', function () {
        // having the 'object' property inside
        var property = {value:'First'};
        return {
            getProperty: function () {
                return property;
            },
            setProperty: function (value) {
                property.value = value;
            }
        }});

这两种解决方案都有效,因为它们正在复制对包含值的对象的引用,而不是复制值本身。