如何在离子操作表中调用来自不同控制器的方法?

时间:2015-09-28 16:29:00

标签: angularjs angularjs-scope ionic-framework angularjs-service angularjs-controller

假设一个典型的Ionic action sheet服务电话:

BMT

...如何通过从两个不同的控制器调用方法来使动作更加多样化?假设我有一个加载内容的控制器和一个加载注释模式的控制器,我可能想调用它们各自的方法:

app.controller('MainCtrl', function($scope, $ionicActionSheet) {
  $scope.showDetails = function() {
    $ionicActionSheet.show({
     buttons: [
       { text: 'Complete' }
     ],
     destructiveText: 'Delete',
     titleText: 'Update Todo',
     cancelText: 'Cancel',
     buttonClicked: function(index) {
       return true;
     }
   });
  }
})

鉴于控制器的隔离范围,我不能像我一样简单地调用buttonClicked: function(index) { if (index == 0) { // call method from controller 1 } else if (index == 1) { // call method from controller 2 } } 。我查看了$scope.scopeMethod()$broadcast,但those techniques似乎是$emit的污染,效率低下。

根据以下尝试的解决方案,我整理了一个简单的演示:http://codepen.io/anon/pen/yYgPXQ

非常感谢。

2 个答案:

答案 0 :(得分:1)

不确定您需要什么,但我认为您想要的是一个服务方法来包装活动表服务电话:

app.factory('myActions', function ($ionicActionSheet) {
    function showActionSheet(params, callback) {
        $ionicActionSheet.show({
            buttons: [{
                text: params.text
            }],
            destructiveText: params.action,
            titleText: params.title,
            cancelText: 'Cancel',
            buttonClicked: function (index) {
               if(callback){
                   callback();
               }
               return true;
            }
        });

    }

    return showActionSheet;

});

在控制器中:

$scope.showDetails = function() {
   myActions({text:'Delete'}, $scope.doSomething);
}

$scope.doSomething = function(){
   alert('I did it!');
}

如果这不是你想要的关于按钮回调...如果没有滥用事件也不是很糟糕,或者按钮回调也可以连接到可能注入控制器的其他服务方法

答案 1 :(得分:1)

如果我理解您想要根据操作表的操作使用不同方法的问题。

我会为此使用服务。角度服务是:

  

Angular服务是连接在一起的可替代对象   使用依赖注入(DI)。您可以使用服务来组织和   在您的应用中共享代码。

技术上$ionicActionSheet是一项服务。

服务是单身,因此,一旦创建,它们就可以在您的应用程序中使用,并最终也可以共享数据。

创建服务的最简单方法是:

app.factory('myService', function() {

    var factory = {}; 

    factory.method1 = function() {
            //..
        }

    factory.method2 = function() {
            //..
        }

    return factory;
});

这里我们创建了一个导出2个方法的对象:method1method2。 一旦定义了服务,就可以将其注入控制器并使用其成员:

app.controller('MainCtrl', function($scope, $ionicActionSheet, myService) {
  $scope.showDetails = function() {
    $ionicActionSheet.show({
     buttons: [
       { text: 'Complete' }
     ],
     destructiveText: 'Delete',
     titleText: 'Update Todo',
     cancelText: 'Cancel',
     buttonClicked: function(index) {
    myService.method1();
        return true;
     }
   });
  }
});

此处注入了新服务myService

app.controller('MainCtrl', function($scope, $ionicActionSheet, myService)

并在单击按钮时调用它:

myService.method1();

有时您可能会发现使用关键字.service创建的服务:

app.service('myService', function() {

}

对于差异,您可以阅读更多here

如果想看一个有效的例子,可以查看plunker

dataService是一个返回对象数组的服务,它将在您的视图中显示。当用户按下完整按钮时,将调用dataService.markAsComplete(id)。此方法将数组的元素设置为已完成。 按删除键也会发生同样的事情。此时将调用dataService.deleteCity(id),并且数组中的元素将被标记为已删除。

您的$scope.showDetails看起来像这样:

$scope.showDetails = function(id) {
   $ionicActionSheet.show({
     buttons: [{
       text: 'Complete'
     }],
     destructiveText: 'Delete',
     titleText: 'Update Todo',
     cancelText: 'Cancel',
     buttonClicked: function(index) {
     if (index === 0)
     {
         $scope.cities = dataService.markAsComplete(id);
         return true;
     } 
     return false;
   },
   destructiveButtonClicked : function() {
       $scope.cities = dataService.deleteCity(id);
       return true;
   }      
});

<强>更新

在我们的对话之后,我创建了一个codepen,您可以在其中查看操作表如何调用服务,获取一些数据,打开显示数据的模式。

您的控制器依赖于某些服务:$ionicActionSheet$ionicModal和我们的自定义CommentSrvc(已注入这些服务):

.controller('AppCtrl', function($scope, $ionicActionSheet, $ionicModal, CommentSrvc) {
     $scope.modal = null;
     $scope.comments = [];
}); 

正如您所看到的,它定义了2个元素:我们的模态和将由服务提取的注释列表。

操作表将打开一个模态:

$ionicActionSheet.show({
  titleText: 'My Title',
  buttons: [{
    text: 'Upload'
  }, {
    text: 'Comments'
  }],
  buttonClicked: function(index) {
    if (index == 0) {
      // Upload
      return false;
    } else if (index == 1) {
      // Comments
      $scope.openModal();
    }

    return true;
  },
  cancelText: 'Cancel',
  cancel: function() {
    console.log('CANCELLED');
  }
});
你可以在$scope.openModal();

中看到

之前已创建模态:

  function createModal() {
    $ionicModal.fromTemplateUrl('comments-modal.html', {
      scope: $scope,
      animation: 'slide-in-up'
    }).then(function(modal) {
      $scope.modal = modal;
    });
  }

并保存在我们的范围内。

现在,当打开模态(显示之前)时,它将调用服务,获取数据并将数据数组放在$scope.comments列表中,如下所示:

$scope.openModal = function() {
    CommentSrvc.fetchData()
      .then(function(result) {
        console.log(result);
        $scope.comments = result;
        $scope.modal.show();
      })
      .catch(function(reason) {
        $scope.comments = [];
        // Show error here!     
      });
};

CommentSrvc.fetchData()将返回一个承诺原因,大概是,我们将在那里调用某种$http服务。如果操作成功,则回调(请参阅.then分支)将在$scope.comments中提供返回的数据并打开模式:$scope.modal.show()

这里的服务做得不多。它只是暴露了一个方法fetchData,它返回一个项目数组 我已经使用了一个承诺,因为承诺可以被链接,$http会返回承诺,无论如何:

  function fetchData() {
    var deferred = $q.defer();

    var data = [{your data}];

    deferred.resolve(data);

    return deferred.promise;
  }

最后,我使用指令comments-modal.html更改了您的模态ng-repeat,以显示$scope.comments中存储的所有数据:

<div class="item item-avatar" href="#" ng-repeat="comment in comments">
    <img src="../img/{{comment.image}}">
    <h2>{{comment.title}}</h2>
    <p>{{comment.body}}</p>
</div>