4

В моем проекте AngularJS у меня есть задача: при заполнении обеими директивами с md-автозаполнением из кода внизу директива должна отображаться сразу без какой-либо кнопки. И когда я нажимаю крестик (как на картинке, чтобы очистить поле автозаполнения) блок будет скрывать и без каких-либо кнопокКак показать и скрыть блок кода в AngularJS

Моего код работает не так правильно

И обратите внимание на ошибку в браузере консоли пожалуйста.

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>

ответ

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; 
    }; 
}); 
+0

Спасибо годов. Но есть некоторые моменты, которые не работают: 1) Мне нужно показать блок, когда оба поля будут заполнены. Но на данный момент достаточно выбрать второй для отображения блока; 2) При очистке блока и выборе другого блок снова не отобразится (если очистить первое поле); – Andrey

+0

Я не хочу делать домашнее задание для вас. В этом примере показаны два способа связи от директивы к контроллеру: вызов определенной функции директивы или выдача настраиваемого события. Ваш контроллер может использовать тот или другой или оба. Как ** вы это сделаете? – georgeawg

Смежные вопросы