壹 ❀ 引html
angularjs開發中,組件件相互通訊傳值是再廣泛不過的操做了,好比我在父做用域中獲取了一個數據,想要傳遞給子組件使用,作簡單的作法就是經過scope傳遞,好比這樣:angularjs
<body ng-controller="myCtrl as vm"> <echo-demo data='vm.echo'></echo-demo> </body>
angular.module('myApp', []) .controller('myCtrl', function ($timeout) { let vm = this; vm.echo = { name: '聽風是風' }; }).directive('echoDemo', function () { return { restrict: 'EA', template: '<div>{{$ctrl.name.name}}</div>', replace: true, scope: { data: '<' }, controllerAs: '$ctrl', controller: function ($scope) { let self = this; self.$onInit = function () { self.name = $scope.data; }; } } });
拷貝,正常子組件會顯示 聽風是風。dom
咱們將問題升級,假設父獲取的數據爲異步操做,好比咱們將上方代碼中父控制器的變量外層添加定時器模擬異步操做,其它不變:異步
$timeout(() => { vm.echo = { name: '聽風是風' }; }, 3000);
你會發現這樣子組件就拿不到數據了,由於異步的問題,子組件初始化會先執行,此時數據爲undefined。那麼怎麼解決呢?this
貳 ❀ 解決異步通訊spa
第一種最多見,直接不用scope傳遞了,改用事件通訊,父何時拿到值,就開始派發事件,子組件內響應監聽。rest
// 父做用域 利用定製器模擬異步請求 $timeout(() => { $scope.$broadcast('傳數據啦',data); }, 3000); // 子做用域 $scope.$on('傳數據啦', function (event, data) { // 拿到data了... });
有沒有更簡單的辦法,有,給組件名上添加一個ng-if就行了,像這樣:code
<echo-demo data='vm.echo' ng-if="vm.echo"></echo-demo>
添加了ng-if後你會發現即使父做用域初始化數據外層有$timeout也不要緊,這是由於ng-if的本意就是,當ng-if後的數據何時不爲false才加載dom,因此這裏就成了何時父做用域拿到數據,組件纔開始渲染加載。htm
真的是很巧妙的借用了ng-if的特性,解決了異步傳值的問題。你們若是對於angularjs事件通訊有疑問能夠閱讀 angularjs事件通訊$on,$emit,$broadcast詳解 這篇文章。blog
那麼本文結束。