双向绑定在使用自定义指令时在AngularJS中不能立即工作

时间:2016-04-19 06:08:50

标签: javascript angularjs angularjs-directive angularjs-scope angularjs-ng-repeat

Plunkr

我有一个简单的自动完成下拉列表。当我只使用控制器时,它工作正常。

我想让它可重用,所以我制作了一个自定义指令,其中包含隔离范围

但问题是当我在搜索文本框中输入时,它不会立即调用分配给$('html,body').animate({ scrollTop: $('#myDivWhereToBeScrolled').offset().top }, 1000); 的控制器功能。当我再次开始打字时,它会调用该函数。同样,它取了我输入的值,而不是当前模型值。

我不熟悉自定义指令......我真的不知道如何立即更新模型并从指令范围传递到控制器范围

另一个想法我无法将函数参数从html传递给控制器​​函数。

我想我必须在某处使用ng-change$apply .. 但我应该在哪里和如何使用?

$digest

这是我的Plunkr: Plunkr

3 个答案:

答案 0 :(得分:1)

嘿,我检查了你的方法并解决了你的问题。

通过输入字段的“ng-change”调用“更改”函数。那没关系。但是ng-model目前还没有更新。因此,只需提供一个带有输入值的参数。

DataTable dt = new DataTable();
var v = (bool)dt.Compute("true AND true AND false OR false OR false OR true", "");

您需要提供具有正确属性名称的JSON对象。在这种情况下,我们路由出隔离的范围,因此我们需要以这种方式调用它(使用相同的属性名称“searchText”):

ng-change="change({searchText:selected})"

所以最终的“改变”功能应如下所示:

change="SearchCurrencyOnSearchTextChange(searchText)"

我还删除了一些你的CSS隐藏和显示方法。如果你使用ng-show和jquery来显示/隐藏东西,它很快就会让你大吃一惊。尽量坚持使用。

我还将你的指令从“attribute”更改为“element”指令; D

https://plnkr.co/edit/8sNVFLGOfEcjeLw58Wb6?p=preview

答案 1 :(得分:1)

我尝试将模板和控制器移动到您的指令中,以便您可以重复使用它。我为分配给controllerAs属性的ViewModel创建了一个控制器别名。希望这有助于指导您朝着正确的方向前进:

// Main App
var app = angular.module("app", ['autofillApp']);

app.controller("appCtrl", function ($scope, $http) {
    // Main app controller.
});


//Directive App.........................
var autofillApp = angular.module('autofillApp', []);

autofillApp.directive('autofillDropdown',function(){


    var AutoFillCtrl = function() {

      var vm = this;

      // Get autofill data for country...
    vm.SearchCurrencyOnSearchTextChange = function () {
        if (vm.searchTextCurrency === null || vm.searchTextCurrency === '' || vm.searchTextCurrency ===undefined) {
            vm.IsFocused = false;
            document.getElementById('currencySearchList').style.display = "none";
        }
        else {
            vm.IsFocused = true;
            document.getElementById('currencySearchList').style.display = "block";

            vm.SearchCurrencies = vm.GetFilteredData(vm.searchTextCurrency);
        }
    };

    //Get autofill Result on search for Currency
    vm.AutoFillCurrency = function (currency) {
        vm.IsFocused = false;
        document.getElementById('currencySearchList').style.display = "none";
        vm.searchTextCurrency = currency.Name;
    };

    vm.data = [

        {
            Id: 1,
            Name:"Dollar"
        },
        {
            Id: 2,
            Name: "Pound"
        },
        {
            Id: 3,
            Name: "Rupee"
        },
        {
            Id: 4,
            Name: "Yan"
        },

    ];

    vm.GetFilteredData = function (name) {
        var filteredItems = [];
        name = name.toLowerCase();
        for (var i = 0; i < vm.data.length; i++) {
            var result = vm.data[i].Name.toLowerCase().search(name);
            if (result != -1) {
                filteredItems.push(vm.data[i]);
            }
        }

        return filteredItems;
    };

    };

    AutoFillTmpl = '<div class="pos_Rel"><input placeholder="Search Currency e.g. dollar,pound,rupee" type="text" ng-change="vm.change()" ng-model="selected" class="form-control width_full" /><ul ng-show="focused && items" id="currencySearchList"><li class="autofill" ng-repeat="result in vm.items" ng-click="vm.onSelect(result)" ng-bind="result.Name"></li></ul></div>';

    return {

    restrict:'A',
    controller: AutoFillCtrl,
    controllerAs: 'vm',
    bindToController: true,
    template: AutoFillTmpl,
    scope: {
        'items': '=autofillItems',
        'selected': '=autofillSelected',
        'change': '&autofillChange',
        'focused': '=autofillFocus',
        'onSelect': '&autofillOnselect'
    }
};

});

答案 2 :(得分:1)

这是工作JSFiddle,需要添加监视服务..

controller: function($scope){
      $scope.$watch("selected", function(newVal, oldVal){
        $scope.change();
      })
    }