簡體   English   中英

如何將數據從指令模板傳遞給控制器​​?

[英]How to Pass data from directive template to controller?

我正在構建某種日期選擇器,實際上是2個日期選擇器。 一個用於開始日期,另一個用於結束日期。每個datepicker元素生成一個包含2個輸入標記的模板()。 我想將數據從input的value屬性傳遞給控制器​​。 我試圖在內部范圍中定義字段,這些字段是雙向數據綁定(dateOne和dateTwo)但顯然沒有效果,並且在兩個字段之間沒有傳遞實際數據。 我的另一種方法是使用ng-model,但我對這個功能沒什么好處,我不知道這個規則。 這是我的代碼

angular.module('directives', [])
    .directive('datepicker', ['$timeout',function ($timeout) {
        // Runs during compile
        return {
            scope: {
                id: '@',
                "class": '@',
                dateOne: '=',
                dateTwo: '='
            },
                restrict: 'E', // E = Element, A = Attribute, C = Class, M = Comment
                template: '<div id="{{id}}" class="{{class}}">'+
                        '<div class="date-wrapper">'+
                            '<label for="datepicker-start">From:</label>'+
                            '<div class="fieldWrapper">'+
                                '<input id="datepicker-start" type="date" placeholder="Select date" value={{dateOne}} />'+
                                '<a class="calendar"></a>'+
                            '</div>'+
                        '</div>'+
                        '<div class="date-wrapper">' +
                            '<label for="datepicker-end">To:</label>' +
                            '<div class="fieldWrapper">' +
                                '<input id="datepicker-end" type="date" placeholder="Select date" value={{dateTwo}}/>' +
                                '<a class="calendar"></a>' +
                            '</div>' +
                        '</div>'+
                        '</div>'
                        ,
                replace: true,
            link: function($scope, iElm, iAttrs, controller) {
                console.log('directive link function');
                console.log('directive iAttrs', iAttrs);
                $(".date-wrapper").each(function (index) {
                    console.log('directive index', index);
                    $input = $(this).find('input');
                    $btn = $(this).find('.calendar');

                    console.log('input', $input[0]);
                    console.log('btn', $btn[0]);

                    $input.attr('type', 'text');
                    var pickerStart = new Pikaday({
                        field: $input[0],
                        trigger: $btn[0],
                        container: $(this)[0],
                        format: 'DD/MM/YYYY',
                        firstDay: 1
                    });
                    $btn.show();
                });

            }
        };
}]);

------------------------更新代碼------------------------ -----------

angular.module('directives', [])
    .directive('datepicker', ['$timeout',function ($timeout) {
        // Runs during compile
        return {
            scope: {
                id: '@',
                "class": '@',
                dateOne: '=',
                dateTwo: '='
            },
                restrict: 'E', // E = Element, A = Attribute, C = Class, M = Comment
                template: '<div id="{{id}}" class="{{class}}">'+
                        '<div class="date-wrapper">'+
                            '<label for="datepicker-start">From:</label>'+
                            '<div class="fieldWrapper">'+
                                '<input id="datepicker-start" type="date"  placeholder="Select date" ng-model=dateOne />' +
                                '<a class="calendar"></a>'+
                            '</div>'+
                        '</div>'+
                        '<div class="date-wrapper">' +
                            '<label for="datepicker-end">To:</label>' +
                            '<div class="fieldWrapper">' +
                                '<input id="datepicker-end" type="date" placeholder="Select date" ng-model=dateTwo />' +
                                '<a class="calendar"></a>' +
                            '</div>' +
                        '</div>'+
                        '</div>'
                        ,
                replace: true,
            link: function($scope, iElm, iAttrs, controller) {
                console.log('directive iAttrs', iAttrs);
                $(".date-wrapper").each(function (index) {
                    console.log('directive index', index);
                    $input = $(this).find('input');
                    $btn = $(this).find('.calendar');

                    console.log('input', $input[0]);
                    console.log('btn', $btn[0]);

                    $input.attr('type', 'text');
                    var pickerStart = new Pikaday({
                        field: $input[0],
                        trigger: $btn[0],
                        container: $(this)[0],
                        format: 'DD/MM/YYYY',
                        firstDay: 1
                    });
                    $btn.show();
                });

                $scope.$watch(iAttrs.dateOne, function (newValue, oldValue) {
                    console.log('newValue', newValue);
                    console.log('oldValue', oldValue);
                }, true);

            }
        };

實際上你幾乎就在那里,我做了一些非常類似於你所描述的東西,這是我解決它的方法(在我的例子中我使用了UI-Bootstrap Date選擇器)。

從指令向控制器發送數據的方式是使用回調,而不是簡單的監視。 如果你曾經使用過=你必須在你的控制器(和指令)中設置監視來監視值的變化,這是不好的做法,總體和額外的代碼。

基本上你需要做的是

  1. 在你的指令定義對象中使用&符號綁定一個回調方法/函數

     scope: { onSelect: "&" // onSelect is our callback function in the ctrl } 
  2. 然后,為回調屬性提供一個綁定到控制器$ scope的函數,但是你傳遞一個函數引用(而不是像ng-changed那樣的函數調用)。 像這樣

    <my-directive on-selected="onSelected"></my-directive>

  3. 然后你定義onSelected應該做什么,假設我想打印選定的日期

     // inside controller $scope.onSelected = function(time) { console.log("Time selected: ", time); } 

請注意,我們將指令中的time參數傳遞給控制器​​,因此, scope.onSelect()實際上是一個scope.onSelect()函數,這意味着它將在調用后返回一個函數(也就是說,如果你提供了一個函數,你可以測試它使用angular.isFunction ),所以你應該調用angular.isFunction函數並提供你的參數scope.onSelect()(time)

scope.selectDate = function(time) {
    if (angular.isFunction(scope.onSelect())) {
        // we use isFunction to test if the callback function actually
        // points to a valid function object
        scope.onSelect()(time); // we pass out new selected date time
      }
  }

這是一個顯示我的意思的插件

  1. 用ng-model = dateOne替換模板中的值,用dateTwo替換相同的值。

  2. 我建議使用專用控制器來執行此指令,而不是在鏈接函數中使用邏輯。

app.directive('someDirective',function(){return {restrict:'A',controller:'SomeController',controllerAs:'ctrl',template:'{{ctrl.foo}}'};});

在這里閱讀更多http://blog.thoughtram.io/angularjs/2015/01/02/exploring-angular-1.3-bindToController.html

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM