简体   繁体   中英

AngularJS- how to hide elements using ng-hide?

I have an app that has been written in AngularJS, and am currently trying to add the functionality to hide the headings of some widgets displayed on one of the web pages when the user selects a checkbox to indicate that they should be hidden.

At the moment, I have a page that displays a number of widgets- on the 'heading' of each widget, there is a 'Settings' button. When the user clicks the Settings button, a dialog box opens up on top of the current page (ie the user does not navigate to another page- the URL does not change at all). That dialog box contains a form with a number of input fields- one of which is a checkbox that I want to use to 'hide' the headings of all of the widgets on the webpage.

I have been following the example at: https://docs.angularjs.org/api/ng/directive/ngHide to try and do this, but can't quite seem to get it working...

I have added the ng-hide attribute to my HTML element, as in the example:

<div data-ng-if="widget.name === 'tag-box'" ng-hide="hideWidgetHeading"> <!-- class="ng-hide"-->
    <div class="divider"></div>
    ...

    <div class="divider"></div>
    <div class="row ui-checkbox-row">
        <label class="col-sm-4 col-xs-6" data-i18n="Hide widget heading:"></label>
        <div class="col-sm-8 col-xs-6">
            <label class="ui-checkbox">
                <input type="checkbox" name="noWidgetHeading" id="noWidgetHeading" ng-true-value= "'YES'" ng-false-value= "'NO'" ng-change="hideWidgetHeading()" ng-click="hideWidgetHeading()" ng-checked="hideWidgetHeading" ng-model="viewModel.hideWidgetHeading">
                <!-- ng-model="viewModel.hideWidgetHeading" -->
                <span></span>
            </label>
        </div>
    </div>
</div>

I defined the hideWidgetHeading() function in the ctrl.js file as follows:

function hideWidgetHeading(){
    if($scope.widgetHeadingCheckbox==false) {
        $scope.$watch('noWidgetHeading', function() {
            $scope.hideWidgetHeading = true; 
            console.log("Value of hideWidgetHeading: ", $scope.hideWidgetHeading);
        });
        return true; 
    } else {
        console.log("hideWidgetHeading() else called (Widget/ctrl.js line 440) ");
        $scope.$watch('noWidgetHeading', function() {
            $scope.hideWidgetHeading = false; //document.getElementById('noWidgetHeading');
        });
        return false; 
    }

    if($scope.hideWidgetHeading) {
        console.log("hideWidgetHeading is true- hide the widget heading: ");

    }
    return $scope.hideWidgetHeading;
}

and I have added the following CSS to my widgets.scss file:

.animate-show-hide.ng-hide {
  opacity: 0;
}

.animate-show-hide.ng-hide-add,
.animate-show-hide.ng-hide-remove {
  transition: all linear 0.5s;
}

.umw-tag-box {
  opacity: 1;
}

When I load my page as it is presently, when I click the Settings button, the dialog opens up. If I then check the 'Hide widget heading' checkbox, and click Submit, the debug that I have added displays the following in the console:

Value of hideWidgetHeading: true

which tells me that the code inside the $scope.$watch(...){...} function is running.

However, if I click the Settings button, and then either don't check the 'Hide widget heading' checkbox, or check it and uncheck it again, and then click Submit, I get the same true value displayed in the console debug, which indicates that the code inside the $scope.$watch(...){...} function is running regardless of whether the 'watched' element changes or not.

Questions

  1. How can I ensure that the code inside the $scope.$watch(...){...} only runs when the 'watched' element (ie the checkbox) has its value changed?

  2. How do I actually 'call' the CSS that I've added to hide the HTML elements on the particular HTML that I want to hide? Or how do I make that CSS 'apply' to the HTML elements that I want to hide?

Edit

I changed the HTML for the checkbox to:

<input type="checkbox" ng-model="checked" name="noWidgetHeading" id="noWidgetHeading">

as suggested, and when I now browse to my page, and open the dialog, it displays the widget as I expect:

小部件

When I click the 'Settings' button on the widget, the 'Configure Item' dialog opens up on top of the page:

配置项目对话框

But when I select the 'Hide widget heading' checkbox, it actually hides the 'Tag' label & input box from the dialog:

复选框隐藏标签元素

The element I want to hide is actually displayed on the page from which the dialog box is opened, not on the dialog box itself... but I can't seem to work out how I can hide that using a control on the dialog... Any suggestions?

So, this should work, it is even the first example shown in their docs , with your code it will be:

<div data-ng-if="widget.name === 'tag-box'" ng-hide="viewModel.hideWidgetHeading"> <!-- class="ng-hide"-->
    <div class="divider"></div>
    ...

    <div class="divider"></div>
    <div class="row ui-checkbox-row">
        <label class="col-sm-4 col-xs-6" data-i18n="Hide widget heading:"></label>
        <div class="col-sm-8 col-xs-6">
            <label class="ui-checkbox">
                <input type="checkbox" name="noWidgetHeading" id="noWidgetHeading" ng-true-value= "'YES'" ng-false-value= "'NO'" ng-change="logWidgetHeading()" ng-click="logWidgetHeading()" ng-checked="viewModel.hideWidgetHeading" ng-model="viewModel.hideWidgetHeading">
                <!-- ng-model="viewModel.hideWidgetHeading" -->
                <span></span>
            </label>
        </div>
    </div>
</div>

you can keep functions on the events if you wan to log values, but there is no need for hiding. The ng-model directive will update your value and the ng-hide should follow.

function logWidgetHeading(){
    console.log("Value of hideWidgetHeading: ", $scope.hideWidgetHeading);
}

What i was saying about function or var: in some cases, i used to have values from the scope that were not updated, and the solution was to introduce a function to be called to retreive the value. It is what i thought you were trying because ng-hide="hideWidgetHeading" shows the same name as your function: function hideWidgetHeading(){ , that's why i first said that the round brackets were missing. So another version would be something like this (without ng-model on purpose, to show an alternate way to modify stuff with your events):

<div data-ng-if="widget.name === 'tag-box'" ng-hide="getHideWidgetHeading()"> <!-- class="ng-hide"-->
    <div class="divider"></div>
    ...

    <div class="divider"></div>
    <div class="row ui-checkbox-row">
        <label class="col-sm-4 col-xs-6" data-i18n="Hide widget heading:"></label>
        <div class="col-sm-8 col-xs-6">
            <label class="ui-checkbox">
                <input type="checkbox" name="noWidgetHeading" id="noWidgetHeading" ng-true-value= "'YES'" ng-false-value= "'NO'" ng-change="toggleWidgetHeading()" ng-checked="isHiddenWidgetHeading">
                <!-- ng-model="viewModel.hideWidgetHeading" -->
                <span></span>
            </label>
        </div>
    </div>
</div>

and the js:

//initialisation to the default value:
$scope.isHiddenWidgetHeading = false;

//function that toggles the value:
$scope.toggleWidgetHeading = function(){
    $scope.isHiddenWidgetHeading = !$scope.isHiddenWidgetHeading;
};

//function to retreive the value:
$scope.getHideWidgetHeading = function(){
    return $scope.isHiddenWidgetHeading;
};

Sorry i was a bit quick in naming vars and such, but you should get what you need here..

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM