Javascript AngularJS:$watch未在更改时触发($include页面的范围问题)

Javascript AngularJS:$watch未在更改时触发($include页面的范围问题),javascript,angularjs,Javascript,Angularjs,Html: Filter: <input type="radio" ng-model="Type" value="Rear"> Rear <input type="radio" ng-model="Type" value="Front"> Front <br> Select: <name-value-select entry="entry" field="axleType" options="filterTypes"></name-valu

Html:

Filter: 
<input type="radio" ng-model="Type" value="Rear"> Rear
<input type="radio" ng-model="Type" value="Front"> Front
<br>
Select:
<name-value-select entry="entry" field="axleType" options="filterTypes"></name-value-select>
  .directive('nameValueSelect', function () {
    return {
    restrict: "E",
    scope: {
        entry: "=",
        field: "@",
        options: "=",
        onInputChange: "&"
    },
    controller: function ($scope) {

        $scope.onChange = function () {
            console.log("selected changed");
            $scope.entry.type = $scope.option.value;
            $scope.onInputChange();
        };

        var getItemForValue = function (value) {
            var item = null;
            $scope.options.forEach(function (_option) {
                if (_option.value == value) {
                    item = _option;
                }
            });
            return item;
        };

        $scope.$watch("entry", function () {
            console.log("entry changed");
            $scope.option = getItemForValue($scope.entry[$scope.field]);
        }, true);

    },
    template: '<select ng-model="option" ng-options="o.Description for o in options" ng-change="onChange()"><option value="" selected="selected">Please Select </option></select>'

};  })
$scope.Description = '';
$scope.entry = {Description: ''};
$scope.Type = 'Front';
$scope.entry.type = '';


$scope.$watch('Type', function (Type) {
    $scope.filterTypes = [];
    $scope.axleTypes = new API.GetAxleTypes(function () {
        angular.forEach($scope.axleTypes, function(axleType) {
            if (axleType.Type == Type) {
                this.push(axleType);
            }
            // if(!$scope.$$phase) $scope.$digest(); // tried this, does not have any affect
    }, $scope.filterTypes); // '}, $scope.filterTypes, true)'--> did nothing for me here     
}); 
    $scope.filterTypes.sort(function (a, b) {
        return a.Description.localeCompare(b.Description);
    });
}); // '}, true)' --> did nothing for me here
    <select ng-model="$parent.selectedFrontAxle" ng-options="axleType.Description for axleType in axleTypes | filterByType: 'Front' | orderBy:'Description'"  id="frontAxles" class="formRequire" required>            
        <option value="" selected>Select Axle Type ..</option>  
    </select>
  <name-value-select   entry="entry" field="axleType" options="filterTypes"></name-value-select>
问题:

Filter: 
<input type="radio" ng-model="Type" value="Rear"> Rear
<input type="radio" ng-model="Type" value="Front"> Front
<br>
Select:
<name-value-select entry="entry" field="axleType" options="filterTypes"></name-value-select>
  .directive('nameValueSelect', function () {
    return {
    restrict: "E",
    scope: {
        entry: "=",
        field: "@",
        options: "=",
        onInputChange: "&"
    },
    controller: function ($scope) {

        $scope.onChange = function () {
            console.log("selected changed");
            $scope.entry.type = $scope.option.value;
            $scope.onInputChange();
        };

        var getItemForValue = function (value) {
            var item = null;
            $scope.options.forEach(function (_option) {
                if (_option.value == value) {
                    item = _option;
                }
            });
            return item;
        };

        $scope.$watch("entry", function () {
            console.log("entry changed");
            $scope.option = getItemForValue($scope.entry[$scope.field]);
        }, true);

    },
    template: '<select ng-model="option" ng-options="o.Description for o in options" ng-change="onChange()"><option value="" selected="selected">Please Select </option></select>'

};  })
$scope.Description = '';
$scope.entry = {Description: ''};
$scope.Type = 'Front';
$scope.entry.type = '';


$scope.$watch('Type', function (Type) {
    $scope.filterTypes = [];
    $scope.axleTypes = new API.GetAxleTypes(function () {
        angular.forEach($scope.axleTypes, function(axleType) {
            if (axleType.Type == Type) {
                this.push(axleType);
            }
            // if(!$scope.$$phase) $scope.$digest(); // tried this, does not have any affect
    }, $scope.filterTypes); // '}, $scope.filterTypes, true)'--> did nothing for me here     
}); 
    $scope.filterTypes.sort(function (a, b) {
        return a.Description.localeCompare(b.Description);
    });
}); // '}, true)' --> did nothing for me here
    <select ng-model="$parent.selectedFrontAxle" ng-options="axleType.Description for axleType in axleTypes | filterByType: 'Front' | orderBy:'Description'"  id="frontAxles" class="formRequire" required>            
        <option value="" selected>Select Axle Type ..</option>  
    </select>
  <name-value-select   entry="entry" field="axleType" options="filterTypes"></name-value-select>
自定义选择控件最初会填充“Front”类型的项,如果我将Rear设置为默认值,则也会填充“Rear”

但是,在单选按钮之间切换时,不会调用“监视”功能,并且“选择”不会填充符合新选择的过滤器类型的项目。

////////////////////////////////////////////////////// 缩小了问题范围: /////////////////////////////////////////////////////

当我把它转移到一个独立的项目时,我发现上面的代码是有效的:-(

以下是原始的select NOT作为自定义指令:

Filter: 
<input type="radio" ng-model="Type" value="Rear"> Rear
<input type="radio" ng-model="Type" value="Front"> Front
<br>
Select:
<name-value-select entry="entry" field="axleType" options="filterTypes"></name-value-select>
  .directive('nameValueSelect', function () {
    return {
    restrict: "E",
    scope: {
        entry: "=",
        field: "@",
        options: "=",
        onInputChange: "&"
    },
    controller: function ($scope) {

        $scope.onChange = function () {
            console.log("selected changed");
            $scope.entry.type = $scope.option.value;
            $scope.onInputChange();
        };

        var getItemForValue = function (value) {
            var item = null;
            $scope.options.forEach(function (_option) {
                if (_option.value == value) {
                    item = _option;
                }
            });
            return item;
        };

        $scope.$watch("entry", function () {
            console.log("entry changed");
            $scope.option = getItemForValue($scope.entry[$scope.field]);
        }, true);

    },
    template: '<select ng-model="option" ng-options="o.Description for o in options" ng-change="onChange()"><option value="" selected="selected">Please Select </option></select>'

};  })
$scope.Description = '';
$scope.entry = {Description: ''};
$scope.Type = 'Front';
$scope.entry.type = '';


$scope.$watch('Type', function (Type) {
    $scope.filterTypes = [];
    $scope.axleTypes = new API.GetAxleTypes(function () {
        angular.forEach($scope.axleTypes, function(axleType) {
            if (axleType.Type == Type) {
                this.push(axleType);
            }
            // if(!$scope.$$phase) $scope.$digest(); // tried this, does not have any affect
    }, $scope.filterTypes); // '}, $scope.filterTypes, true)'--> did nothing for me here     
}); 
    $scope.filterTypes.sort(function (a, b) {
        return a.Description.localeCompare(b.Description);
    });
}); // '}, true)' --> did nothing for me here
    <select ng-model="$parent.selectedFrontAxle" ng-options="axleType.Description for axleType in axleTypes | filterByType: 'Front' | orderBy:'Description'"  id="frontAxles" class="formRequire" required>            
        <option value="" selected>Select Axle Type ..</option>  
    </select>
  <name-value-select   entry="entry" field="axleType" options="filterTypes"></name-value-select>

选择轴类型。。
以下是选择控件作为自定义指令:

Filter: 
<input type="radio" ng-model="Type" value="Rear"> Rear
<input type="radio" ng-model="Type" value="Front"> Front
<br>
Select:
<name-value-select entry="entry" field="axleType" options="filterTypes"></name-value-select>
  .directive('nameValueSelect', function () {
    return {
    restrict: "E",
    scope: {
        entry: "=",
        field: "@",
        options: "=",
        onInputChange: "&"
    },
    controller: function ($scope) {

        $scope.onChange = function () {
            console.log("selected changed");
            $scope.entry.type = $scope.option.value;
            $scope.onInputChange();
        };

        var getItemForValue = function (value) {
            var item = null;
            $scope.options.forEach(function (_option) {
                if (_option.value == value) {
                    item = _option;
                }
            });
            return item;
        };

        $scope.$watch("entry", function () {
            console.log("entry changed");
            $scope.option = getItemForValue($scope.entry[$scope.field]);
        }, true);

    },
    template: '<select ng-model="option" ng-options="o.Description for o in options" ng-change="onChange()"><option value="" selected="selected">Please Select </option></select>'

};  })
$scope.Description = '';
$scope.entry = {Description: ''};
$scope.Type = 'Front';
$scope.entry.type = '';


$scope.$watch('Type', function (Type) {
    $scope.filterTypes = [];
    $scope.axleTypes = new API.GetAxleTypes(function () {
        angular.forEach($scope.axleTypes, function(axleType) {
            if (axleType.Type == Type) {
                this.push(axleType);
            }
            // if(!$scope.$$phase) $scope.$digest(); // tried this, does not have any affect
    }, $scope.filterTypes); // '}, $scope.filterTypes, true)'--> did nothing for me here     
}); 
    $scope.filterTypes.sort(function (a, b) {
        return a.Description.localeCompare(b.Description);
    });
}); // '}, true)' --> did nothing for me here
    <select ng-model="$parent.selectedFrontAxle" ng-options="axleType.Description for axleType in axleTypes | filterByType: 'Front' | orderBy:'Description'"  id="frontAxles" class="formRequire" required>            
        <option value="" selected>Select Axle Type ..</option>  
    </select>
  <name-value-select   entry="entry" field="axleType" options="filterTypes"></name-value-select>

显然这就是问题所在:“ng model=“$parent.selectedfrontaxe”

如果我接受指令“name-value-select”并将其移动到父页面,而不是include语句,它就会工作

但这不是我想要的。所以我需要把它放在包含页面中

但是,如果我使用ng model=“$parent.selectedfrontaxe”并将其添加到include页面上的任何元素,则没有任何效果

任何没有ng model=“$parent.selectedfrontaxe”,仍然没有任何功能

我可以看出问题的范围很广,但我不知道如何纠正它

啊!!!还是没有解决办法

//
//
////////////////////////////////////////////////////////////// Mark Rajcok //////////////////////////////////////////////////////////////

一如既往地感谢您的帮助。虽然,我不认为我在第2点上说得很清楚,当时我说我想让代码预过滤而不是用户。但是我想出来了。所以对于任何希望通过指令抽象出控件的人来说,就像在本例中一样,过滤过程是由用户和用户执行的代码,以下是plunker解决方案:


我不完全理解您的请求,但我假设您希望根据单选按钮组的值动态更改select的内容。select经过筛选和排序,您可以选择要显示的数据字段

你可以看看这个包含了一些修改的演示

HTML

Filter: 
<input type="radio" ng-model="filter.type" value="rear"> Rear
<input type="radio" ng-model="filter.type" value="front"> Front
<br />
Field:
<select ng-model="filter.field" ng-options="item for item in fields"></select>
<br />
Select:
<select ng-model="entry" ng-options="item[filter.field] for item in entries | filter:type=filter.type | orderBy:filter.field">
  <option value="">Default</option>
</select>
<br />
Selected: <span>{{entry}}</span>

<h2>Alternative</h2>
Filter: <span>{{filter}}</span>
<br />
<select ng-model="altentry" ng-options="item[filter.field] for item in altentries | orderBy:filter.field">
  <option value="">Default</option>
</select>
<br />
Selected: <span>{{altentry}}</span>
在中,我修改了代码,允许用户选择“后”或“前”,选择列表将动态更新。所选值在MainCtrl作用域上的
$scope.selected.item
中可用。(我删除的指令中有很多不必要的代码。在使用ng模型时,不需要onChange处理程序。)


应用程序指令('nameValueSelect',函数(){
返回{
限制:“E”,
范围:{
选择编辑项:“=”,
选项:'='
},
模板:。。。
由于ng include创建了一个子作用域,因此所有原语属性都转换为对象属性,这样JavaScript原语继承将按预期工作(即,当值更改时,$MainCtrl中定义的范围对象将更改,而不是在本地作用域上创建新的原语属性)

我相信上面提到的plunker将满足您的“第1点”

现在,我将为“第2点”创建一个plunker(我将在更新此答案时添加注释)


筛选指令中的选择列表:

<name-value-select selected-item="selected.item" choice="choice.type"
 options="myTypes"></name-value-select>

app.directive('nameValueSelect', function () {
    return {
        restrict: "E",
        scope: {
            selectedItem: "=",
            choice:  "=",
            options: "=",
        },
        controller: function($scope)  {
          $scope.$watch('choice', function (selectedType) {
            $scope.selectedItem = '';  // clear selection
            $scope.filterTypes = [];
            angular.forEach($scope.options, function (type) {
              if (type.Type === selectedType) {
                this.push(type);
               }
            }, $scope.filterTypes);
            $scope.filterTypes.sort(function (a, b) {
              return a.Description.localeCompare(b.Description);
            });
          });
        },
        template: '<select ng-model="selectedItem" ' +
         'ng-options="o.Description for o in filterTypes">' +
         '<option value="" selected="selected">Please Select</option>' +
         '</select>'
    };
});

应用程序指令('nameValueSelect',函数(){
返回{
限制:“E”,
范围:{
选择编辑项:“=”,
选项:“=”,
选项:“=”,
},
控制器:功能($scope){
$scope.$watch('choice',函数(selectedType){
$scope.selectedItem='';//清除选择
$scope.filterTypes=[];
angular.forEach($scope.options,函数(类型){
如果(type.type==selectedType){
这个。推(型);
}
},$scope.filterTypes);
$scope.filterTypes.sort(函数(a,b){
返回a.Description.localeCompare(b.Description);
});
});
},
模板:“”+
'请选择'+
''
};
});

如果您为problemMark设置plunker或fiddle演示,效果会更好。请参阅上面写给您的注释。您不希望同一个控制器重复/嵌套。是否可以设置(使用ng include)?或者至少显示您在哪里使用ng include?不清楚ng包含了哪些HTML。我也不明白
$scope.Type
$scope.entry.Type
是用于什么。如果您的指令应该监视单选按钮的更改,那么单选按钮需要使用
entry.Type
。另外,
打开-您的HTML中未指定输入更改,因此您的“&”绑定在指令中无法工作。(顺便说一句,我没有收到您上面的注释通知…您需要使用@Mark。)@MarkRajcok,请参阅sNJ上面的注释dude@MarkRajcok你在吗?