AngularJS之指令中controller與link(十二)

前言

在指令中存在controller和link屬性,對這兩者心生有點疑問,因而找了資料學習下。api

話題

首先咱們來看看代碼再來分析分析。app

第一次嘗試

頁面:函數

    <custom-directive></custom-directive>

腳本:學習

angular
    .module('app',[])
    .directive('customDirective', customDirective);

function customDirective() {
    var directive = {
        restrict: 'EA',
        template: '<div>{{vm.test}}</div>',
        link: function(){},
        controller: directiveController,
        controllerAs: 'vm'
    };

    return directive;
}

function directiveController() {
    var vm = this;
    vm.test = "I'm from Controller";
}

 

【注】:基礎仍是很是重要,頁面上爲custom-directive,在腳本我寫成customdirective時死都沒出效果,改爲customDirective纔好使。this

第二次嘗試

頁面自定義指令不變,咱們就修改下腳本:spa

angular
    .module('app',[])
    .directive('customDirective', customDirective);

function customDirective() {
    var directive = {
        restrict: 'EA',
        template: '<div>{{test}}</div>',
        link: directiveLink
    };

    return directive;
}


function directiveLink(scope,elem,attr) {
    scope.test = "I'm from Link";
}

到這裏,咱們不只要開始思索:指令中的controller和link均可以實現一樣的效果,那在指令中放這兩個屬性幹嗎?咱們的代碼究竟是放在controller仍是link中?rest

咱們首先來看看當兩者一塊兒使用時,呈現結果的順序即在編譯先後生成的順序。code

controller和link編譯順序

咱們將腳本進行修改以下:blog

angular
    .module('app',[])
    .directive('customDirective', customDirective);

function customDirective() {
    var directive = {
        restrict: 'EA',
        template: '<div>xpy0928{{test}}</div>',
        link: directiveLink,
        controller:directiveController
    };

    return directive;
}

function directiveController($scope){
    $scope.test = " from contrller cnblogs";
}

function directiveLink(scope,elem,attr) {
    scope.test = scope.test + ",and from link cnblogs";
}

生成以下:element

咱們由此得出結論:編譯以前執行控制器(controller),編譯以後執行連接(link)。

可是咱們還未從根本上解決問題,在controller和link應該放哪些代碼?咱們接下來再看一個例子:

var app = angular.module('app',[]);
    
app.directive('customDirective', customDirective);

function customDirective() {
    var directive = {
        restrict: 'EA',
        template: '<child-directive><child-directive>',
       controller: function($scope, $element) {
            $element.find('span').text('hello cnblogs!'); }
    };

    return directive;
}
app.directive("childDirective",childDirective);

function childDirective() {
    var directive = {
        restrict: 'EA',
        template: '<h1>hello xpy0928</h1>',
        replace: true,
        link: function($scope, $element, attr) {
            
            $element.replaceWith(angular.element('<span>' + $element.text() + '</span>'));
        }
    }
    return directive;
}

此時結果應該仍是hello xpy0928仍是hello cnblogs呢?咱們看下結果:

咱們再來將如上進行修改看看:

var app = angular.module('app',[]);
    
app.directive('customDirective', customDirective);

function customDirective() {
    var directive = {
        restrict: 'EA',
        template: '<child-directive><child-directive>',
       link: function(scope, el) {
            el.find('span').text('hello cnblogs!'); }
    };

    return directive;
}
app.directive("childDirective",childDirective);

function childDirective() {
    var directive = {
        restrict: 'EA',
        template: '<h1>hello xpy0928</h1>',
        replace: true,
        link: function($scope, $element, attr) {
            
            $element.replaceWith(angular.element('<span>' + $element.text() + '</span>'));
        }
    }
    return directive;
}

爲何會出現如此狀況?由於在controller函數中此時全部child-directive指令中的link函數還未運行因此此時替換無效。

由此咱們能夠基本得出在controller和link中應該寫什麼代碼的結論:

(1)在controller寫業務邏輯(咱們明白業務邏輯大部分是放在服務中),這裏所說的業務邏輯乃是爲呈現視圖以前而準備的數據或者是與其餘指令進行數據交互而暴露這個api。

(2)在link中主要操做DOM。

總結

指令乃是AngularJS中比較重要的一塊,裏面涉及到的東西也是很是之多,時不時的去往裏面去灌東西,慢慢就會駕輕就熟。