如何在AngularJS中显示和隐藏代码块

时间:2015-12-15 16:52:42

标签: javascript angularjs angularjs-directive angularjs-scope

在我的AngularJS项目中,我有一个任务:当来自代码下的md-autocomplete的两个指令都被填充时,结果指令必须立即显示而没有任何按钮。当我按下十字架(如图片中清除自动完成字段)时,该块也将隐藏,没有任何按钮

我的代码工作不正确

请注意浏览器控制台中的错误。

var app = angular.module('app', ['ngMaterial']);

app.controller('mainCtrl', function($scope){
    $scope.interim = false;

    $scope.go = function(){
        $scope.interim = true;
    };
});

app.directive('point', function(){
    return {
        restrict: 'AE',
        template: '<div layout layout-sm="column">' +
                    '<md-autocomplete ng-disabled="isDisabled" md-no-cache="noCache" md-selected-item="selectedItem" md-search-text-change="searchTextChange(searchText)" md-search-text="searchText" md-selected-item-change="selectedItemChange(item)" md-items="item in querySearch(searchText)" md-item-text="item.display" md-min-length="0" placeholder="{{place}}">' +
                        '<md-item-template>' +
                             '<span md-highlight-text="searchText" md-highlight-flags="^i">{{item.display}}</span>' +
                        '</md-item-template>' +
                    '</md-autocomplete>' +
                '</div>',
        controller: PointCtrl,
        scope: {
            place: '@',
            go: '&'
        }
    }
});

function PointCtrl($scope, $rootScope, $timeout, $q, $log) {

    $scope.simulateQuery = false;
    $scope.isDisabled = false;

    $scope.cities = loadAll();
    $scope.querySearch = querySearch;
    $scope.selectedItemChange = selectedItemChange;


    function loadAll() {
        var allCities = 'London, Manchester, Liverpool, Paris, Lion, Prague, New York, Dallas';

        return allCities.split(/, +/g).map(function (city) {
            return {
                value: city.toLowerCase(),
                display: city
            };
        });
    }

    function querySearch(query) {
        var results = query ? $scope.cities.filter(createFilterFor(query)) : $scope.cities,
            deferred;
        if ($scope.simulateQuery) {
            deferred = $q.defer();
            $timeout(function () {
                deferred.resolve(results);
            }, Math.random() * 1000, false);
            return deferred.promise;
        } else {
            return results;
        }
    }

    function createFilterFor(query) {
        var lowercaseQuery = angular.lowercase(query);

        return function filterFn(city) {
            return (city.value.indexOf(lowercaseQuery) === 0);
        };
    }

    function selectedItemChange(item) {
        $log.log('value: ' + item.display);
        $scope.chosenPoint = item.display;

        $scope.$watch('chosenPoint', function (newVal, oldVal) {
            if (newVal !== '') {             //if autocomplete field is completed
                $scope.go();             //how block with results directive
            } else {
                //$scope.hideBlock();              //if not or cleared - hide block
            }
        });
    }
}

app.directive('results', function() {
    return {
        restrict: 'AE',
        template: '<div style="width: 400px; height: 200px; background-color: red; font-size: 30px; text-align: center" ng-show="interim">I need to show this block when autocomplete fields are filled and hide it when both or, at least, one of the fields are cleared, pressing a cross</div>'
    }
});
<html ng-app="app">
<head>
    <link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/angular_material/1.0.0-rc7/angular-material.min.css">
    <style>
        .resultsBlock {
            width: 400px;
            height: 400px;
            font-size: 14px;
        }

        h3 {  margin: 20px 0;  }

        md-autocomplete button{
            position: relative;
            left: 100px;
            line-height: 20px;
        }

        md-autocomplete input:not(.md-input) {
            font-size: 14px;
            width: 40%;
        }
    </style>
</head>
<body ng-controller="mainCtrl">
    <div class="resultsBlock" layout="column">
            <point place="point_1"></point>
            <h3>Block of text will be shown when both autocomplete fields will be completed</h3>
            <results></results>
            <point place="point_2" go="go()"></point>
    </div>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.6/angular.min.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.6/angular-animate.min.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.6/angular-aria.min.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/angular_material/0.9.4/angular-material.min.js"></script>
    <script src="main.js"></script>
</body>
</html>

1 个答案:

答案 0 :(得分:2)

point指令中,当您单击x删除选择时,将调用selectionItemChange函数并使用item参数未定义。这就是您在控制台中收到错误的原因。

更改您的功能以检测该情况。

您的point指令

function selectedItemChange(item) {

    //add event emitter
    $scope.$emit("pointChange", item);

    if (item) {
        $scope.chosenPoint = item.display;
    } else {
        //set to empty string if 'item' parameter is undefined
        $scope.chosenPoint = '';
    }

    if ( $scope.chosenPoint !== '') { 
        //if autocomplete field is completed
        $scope.go();
    }
}

另请注意添加和事件发射器。在主控制器中监听该事件并使用它来清除该块。

您的主控制器

app.controller('mainCtrl', function($scope){
    $scope.interim = false;

    $scope.$on("pointChange", function (e,item) {
        if (!item) {
          console.log("Clearing block");
          $scope.interim = false;
        }
    });

    $scope.go = function(){
        $scope.interim = true;
    };
});