2015-12-21 4 views
0

У меня проблема с пониманием того, как работает распространение $ scope. У меня 2 вложенные контроллеры:AngularJS scope распространение функции

<div ng-controller="ClientCtrl"> 
    <div class="table-responsive" ng-init="getSocietes()"> 

    <div style="width: 98%; height: 500px;" ag-grid="gridSocietes" class="ag-blue ag-basic"> 

    </div> 

    </div> 
    <div ng-controller="PopupCtrl"> 
     <script type="text/ng-template" id="pmoPopupConfirmDelete.html"> 
    <div class="modal-header"> 
     <h3 class="modal-title">I'm a modal!</h3> 
    </div> 
    <div class="modal-body"> 
     <ul> 
      <li ng-repeat="item in items"> 
       <a href="#" ng-click="$event.preventDefault(); selected.item = item">{{ item }}</a> 
      </li> 
     </ul> 
     Selected: <b>{{ selected.item }}</b> 
    </div> 
    <div class="modal-footer"> 
     <button class="btn btn-primary" type="button" ng-click="ok()">OK</button> 
     <button class="btn btn-warning" type="button" ng-click="cancel()">Cancel</button> 
    </div> 
</script> 
    </div> 
</div> 

Первый контроллер имеет AG-сетку с некоторыми данными в нем. Мне нужно показать всплывающее окно, когда пользователь нажимает кнопку удаления, чтобы попросить его подтвердить удаление строки в таблице.

Я пытаюсь использовать Угловой UI Modal контроллер, как показано на их домашней странице.

Таким образом, у меня есть эти 2 контроллера:

var myApp = angular.module('myApp'); 

myApp.controller('SocietesController', ['$scope', '$http', '$location', '$routeParams', function($scope, $http, $location, $routeParams){ 

$scope.gridSocietes = { 

    columnDefs: [ 
     {headerName: "", field: "", width: 45, suppressSorting: true, suppressResize: true, suppressMenu: true, cellRenderer: actionCellRenderer, suppressSizeToFit: true}, 
     {headerName: "Société", field: "Societe", cellRenderer: societeCellRenderer, sort: 'asc', filter: 'text'}, 
     {headerName: "Adresse", field: "Adresse_1", cellRenderer: adresseCellRenderer, filter: 'text'}, 
     {headerName: "Code postal", field: "CP", width: 100, suppressSizeToFit: true, filter: 'text'}, 
     {headerName: "Ville", field: "Ville", filter: 'text'}, 
     {headerName: "Tel", field: "Tel", width: 120, suppressSizeToFit: true, filter: 'text'}, 
     {headerName: "Fax", field: "Fax", width: 120, suppressSizeToFit: true, filter: 'text'}, 
     {headerName: "E-mail", field: "Email", filter: 'text'}, 
     {headerName: "Site Web", field: "Site_Web", filter: 'text'}, 
     {headerName: "Utilisateurs", width: 100, cellRenderer: usersCellRenderer, suppressSorting: true, suppressResize: true, suppressMenu: true, suppressSizeToFit: true} 

    ], 
    enableColResize: true, 
    enableSorting: true, 
    enableFilter: true, 
    rowSelection: 'single', 
    rowData: null, 
    angularCompileRows: true 
}; 

$scope.getSocietes = function(){ 
    $http.get('/api/societes').success(function(response){ 
     $scope.societes = response; 
     $scope.gridSocietes.api.setRowData(response); 
     $scope.gridSocietes.api.sizeColumnsToFit(); 
    }); 
} 

$scope.supprimerSociete = function(id, index){ 
    console.log($scope) 
    alert('go'); 
    openPopup('sm', 'pmoPopupConfirmDelete.html') 
    return; 
    $http.delete('/api/societes/'+id).success(function(response){ 
     $scope.societes.splice(index, 1); 
     $scope.gridSocietes.api.setRowData($scope.societes); 
    }); 
} 

console.log($scope) 

}]); 

и контроллер Popup:

var myApp = angular.module('myApp'); 

myApp.controller('PopupCtrl', ['$scope', function ($scope, $uibModal, $log) { 
$scope.items = ['item1', 'item2', 'item3']; 

$scope.animationsEnabled = true; 

$scope.openPopup = function (size, template) { 

var modalInstance = $uibModal.open({ 
    animation: true, 
    templateUrl: 'pmoPopupConfirmDelete.html', 
    controller: 'ModalPopupCtrl', 
    size: size, 
    resolve: { 
    items: function() { 
     return $scope.items; 
    } 
    } 
}); 

modalInstance.result.then(function (selectedItem) { 
    $scope.selected = selectedItem; 
}, function() { 
    $log.info('Modal dismissed at: ' + new Date()); 
}); 
}; 

$scope.toggleAnimation = function() { 
    $scope.animationsEnabled = !$scope.animationsEnabled; 
}; 

}]); 


// Please note that $modalInstance represents a modal window (instance) dependency. 
// It is not the same as the $uibModal service used above. 

myApp.controller('ModalPopupCtrl', function ($scope, $uibModalInstance, items) { 

$scope.items = items; 
$scope.selected = { 
    item: $scope.items[0] 
}; 

$scope.ok = function() { 
    $uibModalInstance.close($scope.selected.item); 
}; 

$scope.cancel = function() { 
    $uibModalInstance.dismiss('cancel'); 
}; 
}); 

Я пытаюсь понять, почему функция $ scope.supprimerSociete в первом контроллере не см. функцию OpenPopup во втором контроллере.

Я пробовал немало вещей, но функция OpenPopup никогда не появляется в области 1-го контроллера (даже когда я пытаюсь вызвать его с помощью $ scope.OpenPopup), тогда как все, начиная с 1-го контроллера, появляется в Popup контроллер, когда я регистрирую $ scope в нем ...

Что мне там не хватает?

Thx заранее!

+1

ChildScope наследует функции родителя, но родитель не знает функции своих детей. – Pjetr

ответ

0

Вы можете с легкостью передать свой товар, разрешив во время открытия $uibModal, а затем вы можете сдать этот товар обратно в обещание с близким.

С этим вы можете удалить элемент в тесном обратном вызове, если был нажат yes. Чтобы увидеть это в действии, просмотрите демонстрационную версию ниже или в этом fiddle.

Трудно понять, почему ваш код не работает, потому что я не вижу вызова supprimerSociete и как вы добавляете контроллеры. Я могу только догадываться, что прицелы так:

  • SocietesController (родительская сфера)
    • ClientCtrl (ребенок)
      • popupCtrl (ребенок ClientCtrl)

Тогда, если вы хотите использовать $ sco pe методов clientCtrl или PopupCtrl, они, конечно, не существуют, потому что родитель не наследует ничего от детей. Пожалуйста, прочитайте больше о scopes и о scope inheritance.

Также ваш метод вызова openPopup выглядит странно, потому что такого метода нет. Если вы определяете метод на $scope, он должен быть вызван следующим образом: $scope.openPopup() (если он доступен в $ scope).

Если вы хотите, чтобы всплывающее окно повторно использовалось, я бы создал фабрику для этого, тогда вы можете впрыснуть туда, где вам это нужно.

angular.module('demoApp', ['ui.bootstrap']) 
 
.controller('MainController', function ($scope, $uibModal, $log) { 
 

 
    $scope.items = ['item1', 'item2', 'item3']; 
 

 
    $scope.animationsEnabled = true; 
 

 
    $scope.delete = function (item) { 
 
\t \t console.log('del', item); 
 
    var modalInstance = $uibModal.open({ 
 
     animation: $scope.animationsEnabled, 
 
     templateUrl: 'myModalContent.html', 
 
     controller: 'ModalInstanceCtrl', 
 
     size: 'lg', 
 
     resolve: { 
 
     /*items: function() { 
 
      return $scope.items; 
 
     },*/ 
 
     item: function() { 
 
     \t // pass item to delete 
 
      return item; 
 
     } 
 
     } 
 
    }); 
 

 
    modalInstance.result.then(function (deleteItem) { 
 
     var index = $scope.items.indexOf(deleteItem); 
 
     
 
     $scope.items.splice(index,1); 
 
    }, function() { 
 
     $log.info('Modal dismissed at: ' + new Date()); 
 
    }); 
 
    }; 
 

 
    $scope.toggleAnimation = function() { 
 
    $scope.animationsEnabled = !$scope.animationsEnabled; 
 
    }; 
 

 
}); 
 

 
// Please note that $modalInstance represents a modal window (instance) dependency. 
 
// It is not the same as the $uibModal service used above. 
 

 
angular.module('demoApp').controller('ModalInstanceCtrl', function ($scope, $uibModalInstance, item) { 
 

 
\t $scope.item = item; 
 
    
 
    $scope.ok = function() { 
 
    $uibModalInstance.close($scope.item); 
 
    }; 
 

 
    $scope.cancel = function() { 
 
    $uibModalInstance.dismiss('cancel'); 
 
    }; 
 
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.js"></script> 
 

 
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" 
 
rel="stylesheet"/> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.14.3/ui-bootstrap-tpls.min.js"></script> 
 

 
<div ng-app="demoApp" ng-controller="MainController"> 
 
    <script type="text/ng-template" id="myModalContent.html"> 
 
     <div class="modal-header"> 
 
      <h3 class="modal-title">Confirm delete</h3> 
 
     </div> 
 
     <div class="modal-body"> 
 
      Are you sure to delete {{item}}? 
 
     </div> 
 
     <div class="modal-footer"> 
 
      <button class="btn btn-primary" type="button" ng-click="ok()">Yes</button> 
 
      <button class="btn btn-warning" type="button" ng-click="cancel()">No</button> 
 
     </div> 
 
    </script> 
 
    
 
    <ul> 
 
     <li ng-repeat="item in items"> 
 
     {{item}} 
 
     <button ng-click="delete(item)"> 
 
      delete... 
 
     </button> 
 
     </li> 
 
    </ul> 
 
</div>

0

childScope наследует функции родителя, но родитель не знает функцию своих детей.

Вы должны действительно использовать больше файлов для достижения этого. Прежде всего, начните использовать директивы и определите свои функции/переменные как открытый член ваших контроллеров. Если бы вы это сделали, вы бы поняли в тот момент, когда логика ошибочна: clientCtrl.openPopup(); - это то, что вы пробовали делать.

Во-вторых, separation of concerns, вся бизнес-логика должна быть передана службам. Контроллер не должен обрабатывать API-запросы, он должен просто запрашивать данные у службы, отображать их и обрабатывать все DOM-события. Это все.

clientCtrl.openPopup(items) 
    > PopupService.openPopup(items); 

popupCtrl.opened = PopupService.opened; 
popupCtrl.items = PopupService.items; 
0

Спасибо за ваши ответы.

Как было предложено @Pjetr, и с помощью страницы Дэна Вахлина на Github Я использовал угловую модульную услугу, и теперь она работает.

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