1. 程式人生 > >angularJs自定義指令父子指令通訊

angularJs自定義指令父子指令通訊

老規矩,先上效果圖:


首先說一下本文的重點:

1、父指令如何呼叫子指令中的方法;2、子指令如何呼叫父指令中的方法;(都不是通過廣播的方式)

如果有同學還不知道父指令如何通過[email protected]&給子指令傳遞引數,或者一些其他自定義指令的屬性(scope、complie、link……)的話,請查閱官網文件發或者其他文件部落格。

前言:

在自學了一段時間VUE之後,被VUE簡潔的程式碼以及強大的解耦能力深深折服,所有的介面元素都是元件,元件有聰明元件和笨元件之分,聰明元件就是業務元件,負責複雜的業務邏輯,而笨元件則負責一些基本的資料獲取功能,介面顯示等等,比如日期選擇外掛、輪播圖顯示等等,在開發的時候往往需要大量的笨元件。無奈公司標準產品的開發使用的是angularJs,一下子就有一種一夜回到解放前的感覺,這就跟從IntelliJIDEA回到eclipse的感覺是一樣一樣的。由於自學了一段時間VUE,搞的我現在使用angularJs也是使用VUE的思想,想方設法拜託angularJs中凌亂的程式碼,統統用指令解耦。

在angularJs中編寫自定義指令沒有VUE中編寫元件那麼方便,父子元件之間的通訊,作用域的互相引用等等,在angularJs中並沒有VUE中那麼清晰,所以在編寫自定義指令的時候需要特別注意一些問題。

這個demo是基於onsenui寫的,主要用了了裡面的ons-carousel輪播外掛以及ons-icon圖片兩個自定義指令,不過這個對本次總結沒有任何影響。

首先說一下介面結構,這個介面中有三個指令,第一個是page-tab,就是標題狀態列下面可以左右滑動的page1、2、3……的那一行,然後是下面白色區域的頁面page-content,最後是page-tabbar,page-tabbar包含了page-tab以及page-content,首先看一下主頁面的程式碼:

<ons-page class="hg-agency-item" ng-controller="hgAgencyItemController">
    <ons-toolbar>
        <div class="left">
            <ons-back-button></ons-back-button>
        </div>
        <div class="center">
            <span ng-bind="'這個是標題'"></span
> </div> <div class="right"> <ons-toolbar-button> <ons-icon icon="ion-search"></ons-icon> </ons-toolbar-button> </div> </ons-toolbar> <ons-page class="c-p"> <page-tabbar data="tabItems" tab-num="4"></page-tabbar> </ons-page> </ons-page>

很簡單,就是在內容介面直接引用了page-tabbar指令,傳入兩個引數,data是資料,tab-num是page-tab顯示的tab的個數,然後看一下controller:

由於部分資料不方便顯示,所以打個碼:

name就是tab的顯示值,icon就是圖示。資料很簡單,用起來很簡單,這就是編寫自定義指令的目的。


name就是tab的顯示值,icon就是圖示。資料很簡單,用起來很簡單,這就是編寫自定義指令的目的。

首先來看page-tabbar的html程式碼:

<ons-page>
    <page-tab data="data" item-num="{{tabNum}}" on-click="pageContent.setActiveIndex(index)" var="pageTab"></page-tab>
    <page-content data="data" var="pageContent" postchange="pageTab.setActiveIndex(index)"></page-content>
</ons-page>

也是很簡單:

app.directive('pageTabbar', function () {
return {
restrict: 'E',
replace: false,
templateUrl: 'js/directives/page-tabbar/page.tabbar.template.html',
scope: {
data: '=data',
tabNum:'@tabNum'
},
controller: [
'$scope', '$element', '$attrs', '$transclude',
            function ($scope, $element, $attrs, $transclude) {
angular.element(document).ready(function () {
console.log('pageTabbar ready');
});
}
        ],
link: function (scope,element,attrs) {
        }
    }
});

這個指令的作用只是負責傳遞資料以及,當page-tab或者page-content改變時,通知另一個改變(呼叫指令中暴露的方法),這個是在html程式碼中寫的,指令宣告程式碼中沒有顯示呼叫子指令方法的程式碼,很簡便。

在<page-tab>中屬性var的值表示會在當前page-tabbat的作用域中建立一個pageTab物件,通過$scope.pageTab可以呼叫page-tab指令中暴露的方法;

接下來看page-tab指令:

html程式碼:

<div>
    <ons-carousel var="pageTabCarousel" ons-postchange="console.log('Changed to ' + $event.activeIndex)" overscrollable
                  style="height: 64px"
swipeable auto-scroll item-width="{{itemWidth}}">
        <ons-carousel-item style="background:transparent" ng-repeat="item in list" class="page-tab-carousel-item"
ng-click="onClickItem($index)">
            <div class="page-tab" ng-class="{true:'emphasize',false:'normal'}[currentIndex == $index]" ng-click="onClick({index:$index,item:item})">
                <div class="page-tab page-tab-content">
                    <ons-icon icon="{{item.icon}}"></ons-icon>
                    <span ng-bind="item.name"></span>
                </div>
            </div>
        </ons-carousel-item>
    </ons-carousel>
</div>

js宣告指令程式碼:

app.directive('pageTab', function () {
return {
restrict: 'E',
replace: true,
templateUrl: 'js/directives/page-tab/page.tab.template.html',
scope: {
list: '=data',
onClick: '&onClick',
itemNum: '@'
},
controller: [
'$scope', '$element', '$attrs', '$transclude',
            function ($scope, $element, $attrs, $transclude) {
angular.element(document).ready(function () {
pageTabCarousel.setActiveIndex($scope.currentIndex);
});
$scope.onClickItem = function (n) {
$scope.currentIndex = n;
n >= 1 && n--;
pageTabCarousel.setActiveIndex(n);
};
$scope.currentIndex = 0;
$scope.$parent.$parent[$attrs.var] = {
setActiveIndex: function (index) {
$scope.onClickItem(index);
}
                };
}
        ],
link: function (scope, element, attrs) {
var num = attrs.itemNum - 0;
scope.itemWidth = (100/num).toFixed(0)+"%";
}
    }
});

這裡只講重點,在這個page-tab子指令中,通過這一段程式碼:

$scope.$parent.$parent[$attrs.var] = {
setActiveIndex: function (index) {
$scope.onClickItem(index);
}
};

向父指令提供了一個物件,物件中的方法以及屬性就是子指令暴露的方法,父指令可以通過呼叫這個物件的方法通知子指令做出相應的改變;

同理,page-content也是一樣:

<ons-page
style="
position: absolute;
bottom: 0;
top: 64px;
left: 0;
right: 0px;
">
    <ons-carousel
var="pageContentCarousel"
ons-postchange="onCarouselChange()"
fullscreen
            swipeable
            auto-scroll
            overscrollable>
        <ons-carousel-item ng-repeat="item in list">
            <ng-include src="item.url"></ng-include>
        </ons-carousel-item>
    </ons-carousel>
</ons-page>
app.directive('pageContent', function () {
return {
restrict: 'E',
replace: false,
templateUrl: 'js/directives/page-content/page-content.template.html',
scope: {
list: '=data',
postchange:'&postchange'
},
controller: [
'$scope', '$element', '$attrs', '$transclude',
            function ($scope, $element, $attrs, $transclude) {
angular.element(document).ready(function () {
console.log('pageContent ready');
});
$scope.onCarouselChange = function () {
$scope.postchange({
index:pageContentCarousel.getActiveIndex()
                    });
};
$scope.$parent.$parent[$attrs.var] = {
setActiveIndex:function (index) {
pageContentCarousel.setActiveIndex(index);
}
                };
}
        ],
link: function (scope,element,attrs) {
        }
    }
});

在子指令中通知父指令做出變化的方法是,通過scope的@(對父作用域方法的引用)的方式,直接呼叫父指令傳遞的方法,呼叫方法的時候如果要傳遞引數,需要顯示傳遞引數的key以及value,比如程式碼中的

$scope.onCarouselChange = function () {
$scope.postchange({
index:pageContentCarousel.getActiveIndex()
    });
};

index就是需要傳遞的引數,在父指令方法中獲取引數的也是一樣,引數要一致:



相關推薦

angularJs定義指令父子指令通訊

老規矩,先上效果圖:首先說一下本文的重點:1、父指令如何呼叫子指令中的方法;2、子指令如何呼叫父指令中的方法;(都不是通過廣播的方式)如果有同學還不知道父指令如何通過[email protected]&給子指令傳遞引數,或者一些其他自定義指令的屬性(scop

AngularJS定義指令directive:父類scope和指令中scope之間的通訊

我們知道angularJs中,指令中有scope,父類controller中也有scope,兩者的通訊方式有三中,分別是 scope:false;直接使用父類的scope scope:true;繼承父類的scope scope:{@,=,&}隔離的s

AngularJs定義指令詳解(5) - link

演示 hang cursor off drag font 雙向 事件 date 在指令中操作DOM,我們需要link參數,這參數要求聲明一個函數,稱之為鏈接函數。 寫法: link: function(scope, element, attrs) {  // 在這裏操作DO

AngularJS定義指令directive:scope屬性

一、介紹: 在AngularJS中,除了內建指令如ng-click等,我們還可以自定義指令。自定義指令,是為了擴充套件DOM元素的功能。程式碼中,通過指定directive中的restrict屬性,來決定這個指令是作為標籤(E)、屬性(A)、屬性值(C)、

angularjs定義指令

app.directive('nameunique', function($http) {     return {             require: 'ngModel',//require代表另一個指令的名字,它將會作為link函式的第四個引數          

angularJs定義指令的三種繫結策略

angularJs中指令scope隔離域中有3種繫結策略: .directive("test",function(){ return { scope:{

AngularJS定義指令標籤

建立一個模組 var app = angular.module('app', []);建立一個簡單指令標籤app.directive('alert', function(){ return { template: '<div class="alert">

angularJS 定義指令

angularJS 自定義屬性 類似於過濾器filter,內建了許多方法同時可以自定義方法。 通過angular.model來建立模組物件: -angular.model: controlle

AngularJs定義指令詳解

定義指令的方法:angular.module('myApp', []) .directive('myDirective', function () { // 指令定義放在這裡 }); 第一個引數,指令的名字myDirective 用來在檢視中引用特定的指令。第二

vue 定義拖拽指令

win input app ctrl off title nbsp ini sca <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <t

vue的移動app項目中,定義拖拽指令的問題

喜歡 end direct 需要 不支持 rect 兼容 left dir 使用vue的都知道vue有一個自定義指令,我比較喜歡的就是拖拽的自定義指令,感覺挺方便的! //組件內的拖拽指令 directives: { //組建內自定義指令 drag: {

velocity定義標籤和指令

velocity本身支援自定義標籤和指令的擴充套件, 在 Velocity 模板語言的語法中,以美元符 $ 開頭的為變數的宣告或者引用,而以井號 # 開頭的語句則為 Velocity 的指令(Directive)。 velocity支援的指令有:#set,#forea

解決VUE定義拖拽指令時 onmouseup 與 click事件衝突

功能描述: 如圖,右側懸浮選單按鈕,只支援上下方向拖動,點選時展開或關閉選單。 BUG說明: 滑鼠上下方向拖拽,如果鬆開時滑鼠位於懸浮按鈕上會預設執行click事件,經驗證,click事件與mouse事件的執行順序為onmousedown =》onmouseup =》on

深究AngularJS——定義服務詳解(factory、service、provider)

string targe 返回 config 屬性 doctype 三種方式 啟用 print 前言 3種創建自定義服務的方式。 Factory Service Provider 大家應該知道,AngularJS是後臺人員在工作之余發明的,他主要應用了後臺早就存

angularJS定義過濾器

tex ctrl func turn filter pri spa clas com var app = angular.module(‘myApp‘, []); app.controller(‘myCtrl‘, function($scope) { }); app.fil

angularjs定義filter

var esp ref ram PE info lte scores character angular.Module API Overview Methods info([info]); provider(name, providerType); factory(name

定義父子組件傳值

每一個 lba default kit ons urn 保存 map efault const center = {}; center.on = function(eventName, callback){ if(!center[eventName]){

angularJS定義過濾器篩選列表/下拉框

angularJS過濾器實現篩選列表/下拉框 專案中有時會有這樣的需求:用input輸入框實現對select下拉框或者一個列表的篩選功能。(這是作者寫的一個小demo,請忽略樣式) 篩選的結果: 那麼怎麼用angularJS簡單、便捷地實現這一功能

AngularJS 定義表單驗證$parsers

        當用戶同控制器進行互動,並且ngModelController中的$setViewValue()方法被呼叫時,$parsers陣列中的函式會以流水線的形式被逐個呼叫。第一個$parse被呼叫後,執行結果

angularJS定義服務的幾種方式

actor values sta 初始化 模塊加載 nts 提供者 efi config 在angularJS中定義服務共有四種常見的方式:factory,service,provider,constant,value 使用形式的不同: 1)factory以返回對象的形式定