2016-05-01 8 views
0

Почему $scope.items в First и Second контроллеры все еще имеют ценность First, почему он оленья кожа изменения значения From controller после вызова функции Load()?обмен данными между контроллерами угловых JS

HomeController:

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

Index.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> 

Custom.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; 
      } 
     }; 
    }); 

ответ

0

Причина заключается в том, что вы работаете со строками. Это означает, что, когда вы звоните:

$scope.items = sharedProperties.getProperty(); 

Вы получаете копию своей строки. Для обмена данными между контроллерами, вы можете изменить ваши контроллеры следующим образом:

HTML:

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

ЯШ:

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

Оба эти решения работают, потому что копируют ссылку на объект, который содержит значение вместо копирования самого значения.

1

Проблема заключается в том, что в контроллерах First и Second переменные $scope.items инициализируются при загрузке контроллеров. После этого момента они больше не меняются.

Порядок выполнения здесь заключается в следующем:

  1. контроллер «Первый» инициализируется, наряду с его переменной $scope.items;
  2. Инициализируется контроллер «Второй», а также его переменная $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 events общаться между контроллерами.

Смежные вопросы