admin管理员组

文章数量:1415467

I'm using AngularJs on my project and i've a property on my viewModel that is connected to a dropdown (< select >)

that dropdown have a empty value witch is selected by default, what i want is to prevent user to select that empty value after he select some other value.

ive started to look to $watch, but i dont know if there is some way to cancel the "changing oof that property", some thing like this:

$scope.$watch('myProp', function (newVal, oldVal, scope) {
    if (newVal) { scope.preventDefault(); }
}

any idea, this is the base idea, on a more advanced development i need to ask users for a confirmation.

any ideas?

I'm using AngularJs on my project and i've a property on my viewModel that is connected to a dropdown (< select >)

that dropdown have a empty value witch is selected by default, what i want is to prevent user to select that empty value after he select some other value.

ive started to look to $watch, but i dont know if there is some way to cancel the "changing oof that property", some thing like this:

$scope.$watch('myProp', function (newVal, oldVal, scope) {
    if (newVal) { scope.preventDefault(); }
}

any idea, this is the base idea, on a more advanced development i need to ask users for a confirmation.

any ideas?

Share Improve this question asked Jan 4, 2013 at 12:02 Flavio CF OliveiraFlavio CF Oliveira 5,28514 gold badges43 silver badges64 bronze badges
Add a ment  | 

4 Answers 4

Reset to default 2

what i want is to prevent user to select that empty value after he select some other value

This should happen automatically for you, as long as you don't assign the ng-model property a value initially. So using the <select> shown below, don't initialize $scope.selected_year in your controller:

<select ng-model="selected_year" ng-options="year for year in years"></select>

When the list displays initially, Angular will have added an option like this to the HTML, since $scope.selected_year is not currently set to a valid option/value:

<option value="?" selected="selected"></option>

After selecting a valid choice, that option will magically disappear, so the user will not be able to select it again. Try it in this fiddle.

If the ng-model property already has a valid value assigned when the select list is first displayed, then you can assign a controller function to the undocumented ng-change parameter:

<select ... ng-change="preventUserFromDoingXzy()">

Inside function preventUserFromDoingXzy() you can do what you need to do to control what the user can select, or modify the model.

You can just add ng-required to the select. If there is no initial value to the model then an empty option will be added and on change to a valid value it will remove the empty option

EDITED jsFiddle to revert to previous value and to include the ng-change directive.

From the docs:

The expression is not evaluated when the value change is ing from the model.

This is useful in not interfering with change listeners and creating an infinite loop when reverting the old value in the $apply function

Controller

$scope.options = [{value: 'abc'},{value: 'def'}];

var confirmDialog = function(newVal, yes, no) {
    // obviously not a good way to ask for the user to confirm
    // replace this with a non blocking dialog

    //the timeout is only for the confirm since it's blocking the angular $digest
    setTimeout(function() {
        c = confirm('Is it ok? [' + newVal.value + ']');
        if(c) {
            yes();
        }
        else {
            no();
         }
    }, 0);
};

//Asking for confirmation example
function Ctrl($scope) {
    $scope.options = [{value: 'abc'},{value: 'def'}];

    $scope.select = undefined;
    var oldSelect = undefined;
    $scope.confirmChange = function(select) {
        if(oldSelect) {
            confirmDialog(select,
                 function() {
                    oldSelect = select;
                 },
                 function() {
                    $scope.$apply(function() {$scope.select = oldSelect;});
                });
        }
        else {
            oldSelect = select;
        }
    }
}

Template

<div ng-controller="Ctrl">
  <select ng-model="select" ng-options="o.value for o in options"
          ng-required ng-change="confirmChange(select)">
  </select>
</div>

Probably the easiest, cleanest thing to do would be adding an initial option and setting disabled on it:

<option value="?" selected="selected" disabled></option>

Actually, it is easier to remove the empty value. Suppose you have a list of options:

$scope.options = [{value: ''}, {value: 'abc'},{value: 'def'}];

and a select:

<select ng-model="select" ng-options="o.value for o in options"></select>

Then $watch the model:

$scope.$watch('select', function(value) {
    if (value && value !== '') {
        if ($scope.options[0].value === '') {
            $scope.options = $scope.options.slice(1);
        }
    }
}, true);

See it in action here.

PS Don't forget the objectEquality parameter in the $watch or it won't work!

本文标签: javascriptHow to prevent property change on Angular JSStack Overflow