จะเรียกวิธีที่กำหนดไว้ในคำสั่ง AngularJS ได้อย่างไร


297

ฉันมีคำสั่งนี่คือรหัส:

.directive('map', function() {
    return {
        restrict: 'E',
        replace: true,
        template: '<div></div>',
        link: function($scope, element, attrs) {

            var center = new google.maps.LatLng(50.1, 14.4); 
            $scope.map_options = {
                zoom: 14,
                center: center,
                mapTypeId: google.maps.MapTypeId.ROADMAP
            };
            // create map
            var map = new google.maps.Map(document.getElementById(attrs.id), $scope.map_options);
            var dirService= new google.maps.DirectionsService();
            var dirRenderer= new google.maps.DirectionsRenderer()

            var showDirections = function(dirResult, dirStatus) {
                if (dirStatus != google.maps.DirectionsStatus.OK) {
                    alert('Directions failed: ' + dirStatus);
                    return;
                  }
                  // Show directions
                dirRenderer.setMap(map);
                //$scope.dirRenderer.setPanel(Demo.dirContainer);
                dirRenderer.setDirections(dirResult);
            };

            // Watch
            var updateMap = function(){
                dirService.route($scope.dirRequest, showDirections); 
            };    
            $scope.$watch('dirRequest.origin', updateMap);

            google.maps.event.addListener(map, 'zoom_changed', function() {
                $scope.map_options.zoom = map.getZoom();
              });

            dirService.route($scope.dirRequest, showDirections);  
        }
    }
})

ฉันต้องการโทรติดต่อupdateMap()ผู้ใช้ ปุ่มการกระทำไม่ได้อยู่ในคำสั่ง

วิธีที่ดีที่สุดในการโทรupdateMap()จากคอนโทรลเลอร์คืออะไร?


11
ข้อสังเกตเล็ก ๆ น้อย ๆ : การประชุมไม่ควรใช้เครื่องหมายดอลลาร์สำหรับ 'scope' ในฟังก์ชั่นลิงก์เนื่องจากขอบเขตไม่ได้ถูกแทรกเข้าไป แต่ถูกส่งเป็นอาร์กิวเมนต์ปกติ
Noam

คำตอบ:


369

หากคุณต้องการใช้ขอบเขตแยกคุณสามารถส่งผ่านวัตถุควบคุมโดยใช้การเชื่อมโยงสองทิศทาง=ของตัวแปรจากขอบเขตตัวควบคุม คุณยังสามารถควบคุมคำสั่งเดียวกันหลายอินสแตนซ์บนหน้าเว็บที่มีวัตถุควบคุมเดียวกันได้

angular.module('directiveControlDemo', [])

.controller('MainCtrl', function($scope) {
  $scope.focusinControl = {};
})

.directive('focusin', function factory() {
  return {
    restrict: 'E',
    replace: true,
    template: '<div>A:{{internalControl}}</div>',
    scope: {
      control: '='
    },
    link: function(scope, element, attrs) {
      scope.internalControl = scope.control || {};
      scope.internalControl.takenTablets = 0;
      scope.internalControl.takeTablet = function() {
        scope.internalControl.takenTablets += 1;
      }
    }
  };
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="directiveControlDemo">
  <div ng-controller="MainCtrl">
    <button ng-click="focusinControl.takeTablet()">Call directive function</button>
    <p>
      <b>In controller scope:</b>
      {{focusinControl}}
    </p>
    <p>
      <b>In directive scope:</b>
      <focusin control="focusinControl"></focusin>
    </p>
    <p>
      <b>Without control object:</b>
      <focusin></focusin>
    </p>
  </div>
</div>


11
+1 นี่เป็นวิธีที่ฉันสร้าง API สำหรับส่วนประกอบที่สามารถใช้ซ้ำได้ในเชิงมุม
romiem

5
นี่คือสะอาดกว่าคำตอบที่ยอมรับและ +1 สำหรับการอ้างอิงซิมป์สันถ้าฉันไม่เข้าใจผิด
Blake Miller

44
นั่นคือวิธีที่ฉันแก้ไขปัญหาเดียวกัน มันใช้งานได้ แต่ดูเหมือนแฮ็ค ... ฉันหวังว่าเชิงมุมจะมีทางออกที่ดีกว่าสำหรับเรื่องนี้
Dema

1
ฉันกำลังเรียนรู้เชิงมุมดังนั้นความคิดเห็นของฉันอาจไม่ได้รับน้ำหนักมาก แต่ฉันพบวิธีนี้ง่ายกว่าคำตอบอื่น ๆ และจะทำเครื่องหมายคำตอบที่ถูกต้อง ฉันนำสิ่งนี้ไปใช้ในแอปพลิเคชัน Sandbox โดยไม่มีปัญหา
BLSully

4
คุณควรตรวจสอบเพื่อให้แน่ใจว่าscope.controlมีอยู่ไม่เช่นนั้นที่อื่น ๆ ที่ใช้คำสั่ง แต่ไม่จำเป็นต้องเข้าถึงวิธีการของคำสั่งและไม่มีcontrolattr จะเริ่มโยนข้อผิดพลาดเกี่ยวกับการไม่สามารถตั้งค่าคุณลักษณะบนundefined
CheapSteaks

73

สมมติว่าปุ่มการกระทำที่ใช้ควบคุมเดียวกัน$scopeเป็นคำสั่งเพียงแค่กำหนดหน้าที่updateMapใน$scopeภายในฟังก์ชั่นการเชื่อมโยง คอนโทรลเลอร์ของคุณสามารถเรียกใช้ฟังก์ชันนั้นเมื่อคลิกปุ่มการกระทำ

<div ng-controller="MyCtrl">
    <map></map>
    <button ng-click="updateMap()">call updateMap()</button>
</div>
app.directive('map', function() {
    return {
        restrict: 'E',
        replace: true,
        template: '<div></div>',
        link: function($scope, element, attrs) {
            $scope.updateMap = function() {
                alert('inside updateMap()');
            }
        }
    }
});

fiddle


ตามความเห็นของ @ FlorianF หากคำสั่งใช้ขอบเขตที่แยกสิ่งต่าง ๆ มีความซับซ้อนมากขึ้น นี่คือวิธีหนึ่งในการทำให้มันใช้งานได้: เพิ่มset-fnคุณสมบัติลงในmapคำสั่งที่จะลงทะเบียนฟังก์ชั่นคำสั่งกับคอนโทรลเลอร์:

<map set-fn="setDirectiveFn(theDirFn)"></map>
<button ng-click="directiveFn()">call directive function</button>
scope: { setFn: '&' },
link: function(scope, element, attrs) {
    scope.updateMap = function() {
       alert('inside updateMap()');
    }
    scope.setFn({theDirFn: scope.updateMap});
}
function MyCtrl($scope) {
    $scope.setDirectiveFn = function(directiveFn) {
        $scope.directiveFn = directiveFn;
    };
}

fiddle


เกิดอะไรขึ้นถ้าคำสั่งมีขอบเขตแยก?
Florian F

ขอบคุณ! (บางทีมันอาจจะง่ายต่อการเรียกใช้ฟังก์ชันที่กำหนดไว้ในการควบคุมสั่งของ แต่ผมไม่แน่ใจว่าเกี่ยวกับที่)
Florian F

1
นี่เป็นวิธีที่ดีกว่าถ้าคุณไม่ได้จัดการกับขอบเขตที่แยกออกมา
Martin Frank

คำตอบนี้ตอบคำถาม OP จริง ๆ มันยังใช้ขอบเขตแยกเพื่อที่จะมีขอบเขตแยกคุณจะต้องเพิ่มscopeคุณสมบัติในการประกาศคำสั่ง
Daniel G.

35

แม้ว่ามันอาจเป็นการล่อลวงให้แสดงวัตถุบนขอบเขตแยกของคำสั่งเพื่ออำนวยความสะดวกในการสื่อสารกับมันการทำสามารถนำไปสู่ความสับสน "สปาเก็ตตี้" รหัสโดยเฉพาะอย่างยิ่งถ้าคุณต้องการเชื่อมโยงการสื่อสารนี้ผ่านสองระดับ เพื่อซ้อนคำสั่ง ฯลฯ )

เดิมเราลงเส้นทางนี้ แต่หลังจากการวิจัยเพิ่มเติมพบว่ามันสมเหตุสมผลมากขึ้นและส่งผลให้ทั้งรหัสที่บำรุงรักษาและสามารถอ่านได้เพื่อแสดงเหตุการณ์และคุณสมบัติที่คำสั่งจะใช้สำหรับการสื่อสารผ่านบริการแล้วใช้ $ watch ในคุณสมบัติของบริการนั้น คำสั่งหรือการควบคุมอื่น ๆ ที่จะต้องตอบสนองต่อการเปลี่ยนแปลงเหล่านั้นเพื่อการสื่อสาร

สิ่งที่เป็นนามธรรมนี้ทำงานได้เป็นอย่างดีกับ AngularJS ของเฟรมเวิร์กการพึ่งพาเนื่องจากคุณสามารถฉีดเซอร์วิสลงในรายการใด ๆ ที่จำเป็นต้องตอบสนองต่อเหตุการณ์เหล่านั้น หากคุณดูไฟล์ Angular.js คุณจะเห็นว่าคำสั่งในนั้นใช้บริการและ $ watch ในลักษณะนี้พวกเขาจะไม่เปิดเผยเหตุการณ์ในขอบเขตที่แยก

สุดท้ายในกรณีที่คุณต้องการสื่อสารระหว่างคำสั่งที่ขึ้นอยู่กับอีกคนหนึ่งฉันขอแนะนำให้แบ่งปันตัวควบคุมระหว่างคำสั่งเหล่านั้นเป็นวิธีการสื่อสาร

Wiki ของ AngularJS สำหรับวิธีปฏิบัติที่ดีที่สุดยังกล่าวถึงเรื่องนี้:

ใช้. $ Broadcast (),. $ emit () และ. $ on () สำหรับกิจกรรมอะตอมมิกเหตุการณ์ที่เกี่ยวข้องทั่วโลกในแอปทั้งหมด (เช่นการรับรองความถูกต้องของผู้ใช้หรือการปิดแอป) หากคุณต้องการกิจกรรมเฉพาะสำหรับโมดูลบริการหรือวิดเจ็ตคุณควรพิจารณาบริการควบคุม Directive หรือ Libs ของบุคคลที่สาม

  • $ scope $ watch () ควรแทนที่เหตุการณ์ที่ต้องการ
  • บริการการฉีดและวิธีการโทรโดยตรงยังมีประโยชน์สำหรับการสื่อสารโดยตรง
  • คำสั่งสามารถสื่อสารกันโดยตรงผ่านตัวควบคุมคำสั่ง

2
ฉันไปถึงสองทางแก้ปัญหาโดยสังหรณ์ใจ: (1) เฝ้าดูการเปลี่ยนแปลงของตัวแปรขอบเขตตัวแปร=นั้นมีชื่อเมธอดและอาร์กิวเมนต์ (2) เปิดเผยสตริง one-way-bind @เป็น id หัวข้อและให้ callee ส่งเหตุการณ์ในหัวข้อนี้ ตอนนี้ฉันเห็นวิกิปฏิบัติที่ดีที่สุด ฉันคิดว่ามีเหตุผลที่จะไม่ทำอย่างนั้น แต่ฉันยังไม่ชัดเจนว่ามันทำงานอย่างไร ในกรณีของฉันฉันสร้างคำสั่ง tabset ฉันต้องการเปิดเผยswitchTab(tabIndex)วิธีการ ตัวอย่างเพิ่มเติมได้ไหม
stanleyxu2005

คุณจะไม่เปิดเผยswitchTab(tabIndex)วิธีการคุณจะผูกกับtabIndexตัวแปรเท่านั้น ตัวควบคุมหน้าของคุณอาจมีการกระทำที่เปลี่ยนแปลงตัวแปรนั้น คุณผูก / ส่งตัวแปรนั้นลงในแท็บ Directive ของคุณ แท็บ Directive ของคุณสามารถดูตัวแปรนั้นสำหรับการเปลี่ยนแปลงและดำเนินการ switchTab ตามความเหมาะสมของมันเอง เพราะคำสั่งตัดสินใจเมื่อ / วิธีการควบคุมแท็บขึ้นอยู่กับตัวแปร นั่นไม่ใช่งานของแหล่งข้อมูลภายนอกมิฉะนั้นแหล่งภายนอกต้องมีความรู้เกี่ยวกับการทำงานภายในของคำสั่งซึ่งเป็น m'kay ที่ไม่ดี
Suamere

15

คำตอบของ Oliver - คุณอาจไม่จำเป็นต้องเข้าถึงวิธีการด้านในของ directive เสมอไปและในกรณีเหล่านั้นคุณอาจไม่ต้องการสร้างวัตถุว่างเปล่าและเพิ่มcontrolattr ใน directive เพื่อป้องกันไม่ให้เกิดข้อผิดพลาด ( cannot set property 'takeTablet' of undefined)

คุณอาจต้องการใช้วิธีการในที่อื่น ๆ ภายในคำสั่ง

ฉันจะเพิ่มการตรวจสอบเพื่อให้แน่ใจว่าscope.controlมีอยู่และตั้งค่าวิธีการในลักษณะคล้ายกับรูปแบบโมดูลที่เปิดเผย

app.directive('focusin', function factory() {
  return {
    restrict: 'E',
    replace: true,
    template: '<div>A:{{control}}</div>',
    scope: {
      control: '='
    },
    link : function (scope, element, attrs) {
      var takenTablets = 0;
      var takeTablet = function() {
        takenTablets += 1;  
      }

      if (scope.control) {
        scope.control = {
          takeTablet: takeTablet
        };
      }
    }
  };
});

จุดโดยใช้รูปแบบการเปิดเผยภายในคำสั่งทำให้ความตั้งใจชัดเจนยิ่งขึ้น ทำได้ดีนี่!
JSancho

12

พูดตามตรงฉันไม่เชื่อจริงๆกับคำตอบใด ๆ ในกระทู้นี้ ดังนั้นนี่คือคำตอบของฉัน:

แนวทางการจัดการ (ผู้จัดการ) แนวทาง

วิธีนี้ไม่เชื่อเรื่องพระเจ้าว่าคำสั่ง$scopeนั้นใช้ร่วมกันหรือแยกได้หรือไม่

A factoryเพื่อลงทะเบียนอินสแตนซ์คำสั่ง

angular.module('myModule').factory('MyDirectiveHandler', function() {
    var instance_map = {};
    var service = {
        registerDirective: registerDirective,
        getDirective: getDirective,
        deregisterDirective: deregisterDirective
    };

    return service;

    function registerDirective(name, ctrl) {
        instance_map[name] = ctrl;
    }

    function getDirective(name) {
        return instance_map[name];
    }

    function deregisterDirective(name) {
        instance_map[name] = null;
    }
});

รหัส directive ฉันมักจะใส่ตรรกะทั้งหมดที่ไม่ได้จัดการกับ DOM ภายใน directive controller และการลงทะเบียนอินสแตนซ์ของตัวควบคุมภายในตัวจัดการของเรา

angular.module('myModule').directive('myDirective', function(MyDirectiveHandler) {
    var directive = {
        link: link,
        controller: controller
    };

    return directive;

    function link() {
        //link fn code
    }

    function controller($scope, $attrs) {
        var name = $attrs.name;

        this.updateMap = function() {
            //some code
        };

        MyDirectiveHandler.registerDirective(name, this);

        $scope.$on('destroy', function() {
            MyDirectiveHandler.deregisterDirective(name);
        });
    }
})

รหัสเทมเพลต

<div my-directive name="foo"></div>

เข้าถึงอินสแตนซ์ของตัวควบคุมโดยใช้factory& เรียกใช้วิธีการเปิดเผยต่อสาธารณะ

angular.module('myModule').controller('MyController', function(MyDirectiveHandler, $scope) {
    $scope.someFn = function() {
        MyDirectiveHandler.get('foo').updateMap();
    };
});

วิธีการเชิงมุม

สละใบจากหนังสือเชิงมุมเกี่ยวกับวิธีที่พวกเขาจัดการกับ

<form name="my_form"></form>

ใช้$ parseและการลงทะเบียนคอนโทรลเลอร์บน$parentขอบเขต เทคนิคนี้ใช้ไม่ได้กับ$scopeคำสั่งที่แยกได้

angular.module('myModule').directive('myDirective', function($parse) {
    var directive = {
        link: link,
        controller: controller,
        scope: true
    };

    return directive;

    function link() {
        //link fn code
    }

    function controller($scope, $attrs) {
        $parse($attrs.name).assign($scope.$parent, this);

        this.updateMap = function() {
            //some code
        };
    }
})

เข้าถึงได้โดยใช้คอนโทรลเลอร์ $scope.foo

angular.module('myModule').controller('MyController', function($scope) {
    $scope.someFn = function() {
        $scope.foo.updateMap();
    };
});

"วิธีการเชิงมุม" ดูดีมาก! แม้ว่าจะมีการพิมพ์ผิด: $scope.fooควรเป็น$scope.my_form
Daniel D

ไม่เลยมันจะเป็น$scope.fooเพราะเทมเพลตของเรา<div my-directive name="foo"></div>และnameค่าของแอตทริบิวต์คือ 'foo' <formเป็นเพียงตัวอย่างหนึ่งของคำสั่งเชิงมุมซึ่งใช้เทคนิคนี้
Mudassir Ali

10

ช้าไปหน่อย แต่นี่เป็นวิธีแก้ปัญหาที่มีขอบเขตแยกและ "เหตุการณ์" เพื่อเรียกใช้ฟังก์ชันในคำสั่ง โซลูชันนี้ได้รับแรงบันดาลใจจากโพสต์ SO นี้โดยsatchmorunและเพิ่มโมดูลและ API

//Create module
var MapModule = angular.module('MapModule', []);

//Load dependency dynamically
angular.module('app').requires.push('MapModule');

สร้าง API เพื่อสื่อสารกับคำสั่ง addUpdateEvent เพิ่มเหตุการณ์ในอาร์เรย์เหตุการณ์และ updateMap เรียกใช้ฟังก์ชันเหตุการณ์ทั้งหมด

MapModule.factory('MapApi', function () {
    return {
        events: [],

        addUpdateEvent: function (func) {
            this.events.push(func);
        },

        updateMap: function () {
            this.events.forEach(function (func) {
                func.call();
            });
        }
    }
});

(บางทีคุณต้องเพิ่มฟังก์ชันการทำงานเพื่อลบกิจกรรม)

ในคำสั่งตั้งค่าการอ้างอิงถึง MapAPI และเพิ่ม $ scope.updateMap เป็นเหตุการณ์เมื่อ MapApi.updateMap ถูกเรียก

app.directive('map', function () {
    return {
        restrict: 'E', 
        scope: {}, 
        templateUrl: '....',
        controller: function ($scope, $http, $attrs, MapApi) {

            $scope.api = MapApi;

            $scope.updateMap = function () {
                //Update the map 
            };

            //Add event
            $scope.api.addUpdateEvent($scope.updateMap);

        }
    }
});

ในคอนโทรลเลอร์ "main" เพิ่มการอ้างอิงไปยัง MapApi และเพียงเรียก MapApi.updateMap () เพื่ออัพเดทแผนที่

app.controller('mainController', function ($scope, MapApi) {

    $scope.updateMapButtonClick = function() {
        MapApi.updateMap();    
    };
}

2
ข้อเสนอนี้จะต้องใช้งานได้อีกเล็กน้อยในโลกแห่งความเป็นจริงเมื่อคุณมีคำสั่งหลายประเภทที่เหมือนกันทั้งนี้ขึ้นอยู่กับบริการ API ของคุณ คุณจะแน่ใจได้ว่าอยู่ในสถานการณ์ที่คุณต้องการกำหนดเป้าหมายและเรียกใช้ฟังก์ชันจากคำสั่งที่ระบุเพียงอย่างเดียวและไม่ใช่ทั้งหมด คุณต้องการที่จะปรับปรุงคำตอบของคุณด้วยวิธีการแก้ปัญหานี้หรือไม่?
smajl

5

คุณสามารถระบุแอตทริบิวต์ DOM ที่สามารถใช้เพื่อให้คำสั่งกำหนดฟังก์ชันบนขอบเขตพาเรนต์ ขอบเขตหลักนั้นสามารถเรียกวิธีนี้เหมือนกันได้ นี่คือพลั่ว และด้านล่างเป็นรหัสที่เกี่ยวข้อง

clearfn เป็นคุณลักษณะในองค์ประกอบคำสั่งที่ขอบเขตหลักสามารถส่งผ่านคุณสมบัติขอบเขตซึ่งคำสั่งนั้นสามารถตั้งค่าให้ฟังก์ชั่นที่บรรลุพฤติกรรมที่ต้องการ

<!DOCTYPE html>
<html ng-app="myapp">
  <head>
    <script data-require="angular.js@*" data-semver="1.3.0-beta.5" src="https://code.angularjs.org/1.3.0-beta.5/angular.js"></script>
    <link rel="stylesheet" href="style.css" />
    <style>
      my-box{
        display:block;
        border:solid 1px #aaa;
        min-width:50px;
        min-height:50px;
        padding:.5em;
        margin:1em;
        outline:0px;
        box-shadow:inset 0px 0px .4em #aaa;
      }
    </style>
  </head>
  <body ng-controller="mycontroller">
    <h1>Call method on directive</h1>
    <button ng-click="clear()">Clear</button>
    <my-box clearfn="clear" contentEditable=true></my-box>
    <script>
      var app = angular.module('myapp', []);
      app.controller('mycontroller', function($scope){
      });
      app.directive('myBox', function(){
        return {
          restrict: 'E',
          scope: {
            clearFn: '=clearfn'
          },
          template: '',
          link: function(scope, element, attrs){
            element.html('Hello World!');
            scope.clearFn = function(){
              element.html('');
            };
          }
        }
      });
    </script>
  </body>
</html>

ฉันไม่เข้าใจว่าทำไมมันถึงใช้งานได้ .. เป็นเพราะแอตทริบิวต์ที่ชัดเจนอยู่ในขอบเขตอย่างไร
Quinn Wilson

1
มันกลายเป็นส่วนหนึ่งของขอบเขตของคำสั่งทันทีที่คุณประกาศ (เช่นscope: { clearFn: '=clearfn' })
เทรเวอร์

2

เพียงแค่ใช้ขอบเขต $ parent เพื่อเชื่อมโยงฟังก์ชั่นที่เรียกว่าฟังก์ชั่น directive

angular.module('myApp', [])
.controller('MyCtrl',['$scope',function($scope) {

}])
.directive('mydirective',function(){
 function link(scope, el, attr){
   //use scope.$parent to associate the function called to directive function
   scope.$parent.myfunction = function directivefunction(parameter){
     //do something
}
}
return {
        link: link,
        restrict: 'E'   
      };
});

ใน HTML

<div ng-controller="MyCtrl">
    <mydirective></mydirective>
    <button ng-click="myfunction(parameter)">call()</button>
</div>

2

คุณสามารถบอกชื่อเมธอดเพื่อกำหนดว่าคุณต้องการโทรจากคอนโทรลเลอร์ แต่ไม่มีขอบเขตแยก

angular.module("app", [])
  .directive("palyer", [
    function() {
      return {
        restrict: "A",
        template:'<div class="player"><span ng-bind="text"></span></div>',
        link: function($scope, element, attr) {
          if (attr.toPlay) {
            $scope[attr.toPlay] = function(name) {
              $scope.text = name + " playing...";
            }
          }
        }
      };
    }
  ])
  .controller("playerController", ["$scope",
    function($scope) {
      $scope.clickPlay = function() {
        $scope.play('AR Song');
      };
    }
  ]);
.player{
  border:1px solid;
  padding: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
  <div ng-controller="playerController">
    <p>Click play button to play
      <p>
        <p palyer="" to-play="play"></p>
        <button ng-click="clickPlay()">Play</button>

  </div>
</div>


1

ผ่านการทดสอบ หวังว่าสิ่งนี้จะช่วยให้ใครบางคน

วิธีการง่ายๆของฉัน (คิดว่าแท็กเป็นรหัสต้นฉบับของคุณ)

<html>
<div ng-click="myfuncion"> 
<my-dir callfunction="myfunction">
</html>

<directive "my-dir">
callfunction:"=callfunction"
link : function(scope,element,attr) {
scope.callfunction = function() {
 /// your code
}
}
</directive>

0

บางทีนี่อาจไม่ใช่ตัวเลือกที่ดีที่สุด แต่คุณสามารถทำได้angular.element("#element").isolateScope()หรือ$("#element").isolateScope()เข้าถึงขอบเขตและ / หรือตัวควบคุมของคำสั่งของคุณ


0

วิธีรับตัวควบคุมของ directive ในตัวควบคุมหน้า:

  1. เขียนคำสั่งที่กำหนดเองเพื่อรับการอ้างอิงถึงตัวควบคุมคำสั่งจากองค์ประกอบ DOM:

    angular.module('myApp')
        .directive('controller', controller);
    
    controller.$inject = ['$parse'];
    
    function controller($parse) {
        var directive = {
            restrict: 'A',
            link: linkFunction
        };
        return directive;
    
        function linkFunction(scope, el, attrs) {
            var directiveName = attrs.$normalize(el.prop("tagName").toLowerCase());
            var directiveController = el.controller(directiveName);
    
            var model = $parse(attrs.controller);
            model.assign(scope, directiveController);
        }
    }
  2. ใช้มันใน html ของคอนโทรลเลอร์หน้า:

    <my-directive controller="vm.myDirectiveController"></my-directive>
  3. ใช้ directive controller ในคอนโทรลเลอร์หน้า:

    vm.myDirectiveController.callSomeMethod();

หมายเหตุ: การแก้ปัญหาที่กำหนดให้ใช้งานได้เฉพาะกับตัวควบคุมองค์ประกอบของคำสั่ง (ชื่อแท็กจะใช้ในการรับชื่อของคำสั่งที่ต้องการ)


0

โซลูชันด้านล่างจะมีประโยชน์เมื่อคุณมีคอนโทรลเลอร์ (ทั้งพาเรนต์และไดเรกทีฟ (แยก)) ในรูปแบบ 'controller As'

บางคนอาจพบว่ามีประโยชน์

คำสั่ง:

var directive = {
        link: link,
        restrict: 'E',
        replace: true,
        scope: {
            clearFilters: '='
        },
        templateUrl: "/temp.html",
        bindToController: true, 
        controller: ProjectCustomAttributesController,
        controllerAs: 'vmd'
    };
    return directive;

    function link(scope, element, attrs) {
        scope.vmd.clearFilters = scope.vmd.SetFitlersToDefaultValue;
    }
}

คำสั่งควบคุม:

function DirectiveController($location, dbConnection, uiUtility) {
  vmd.SetFitlersToDefaultValue = SetFitlersToDefaultValue;

function SetFitlersToDefaultValue() {
           //your logic
        }
}

รหัส html:

      <Test-directive clear-filters="vm.ClearFilters"></Test-directive>
    <a class="pull-right" style="cursor: pointer" ng-click="vm.ClearFilters()"><u>Clear</u></a> 
//this button is from parent controller which will call directive controller function
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.