modalService 无法与控制器和视图对话
modalService cannot talk with controller and view
The code at this plnkr 有一个模式,当用户单击 "Click to take quiz" 按钮时会弹出一个模式,该按钮调用一个控制器方法,该方法又调用一个模式服务. 要使 plnkr 正常工作,请单击代码中的任意位置并按 space 栏以不影响语法的方式添加白色 space。这将触发 plnkr 重新初始化应用程序,并在您单击按钮后弹出模式。
问题是当 timeLeft
变量倒计时时,模态中打印的文本不会动态更新。而且,用户的按钮点击不会更新 quizAnswer
变量。简而言之,模式无法与调用控制器和视图进行交互。
需要对plnkr做哪些具体的改动才能让模态文本显示动态倒计时,让模态按钮改变$scope.quizAnswer变量的值?
另外,我一直在仔细阅读the documentation at this link。我认为答案可能与以下内容有关:
1.) 在 open(options)
中传递的 $uibModal
的 options
参数包含参数 scope
,它定义了用于模态内容的父范围,并且还有 属性 bindToController
,当设置为 true
时,将 scope
属性 绑定到 controllerAs
定义的特定控制器。
2.) open(options)
方法returns模态实例,其中包括close(result)
和dismiss(reason)
。
我怀疑解决方案在于这些方法和参数,但我正在寻找很好的例子,希望有经验的人能看到这个问题。
注意:这个问题的解决方案出现在已接受答案下方的评论中,尤其是 link 到另一个包含 2 行代码的帖子,用于将模态按钮点击的结果发回父控制器。
您有很多问题。
首先,navigation.js - 第 16 行的 takeQuiz
应该附加到 $scope
,而不是 this
,因为 this
会根据上下文发生变化.
其次,navigation.js 处的 $scope.$apply
和 $scope.$digst();
- 第 29/30 行是不必要的,因为您已经处于摘要循环中。它们应该被删除,否则它们会触发错误。
最后(这是您问题的核心),您误解了在创建模态实例时如何绑定模态选项。它不是双向绑定;它是从一个对象到另一个对象的单一扩展。因此,尝试绑定到选项(或创建带有 timeRemaining 的串联字符串)将不会在绑定后更新。
相反,一种可能性是在模态内部创建一个事件处理程序并在每次更新时广播,更新模态。此外,如果将正文文本作为前置和附加文本传递,则插入时间戳值会更容易:
您需要在您的导航控制器中注入(并从中广播)$rootScope
,因为 modalService
已在作用域链中非常高的位置注册。
在每个滴答声中,广播剩余时间 navigation.js:
$rootScope.$broadcast('timeRemainingTick', $scope.timeRemaining);
在您的 modalService.js 中,注册以接收控制器分配中的事件:
var timeRemainingUnbind = $scope.$on('timeRemainingTick', function(event, newTick) {
$scope.modalOptions.timeRemaining = newTick;
});
最后,确保通过在模态的关闭事件中调用 timeRemainingUnbind()
来解除事件绑定,以防止内存泄漏:
$scope.modalOptions.ok = function (result) {
timeRemainingUnbind();
$modalInstance.close(result);
};
$scope.modalOptions.close = function (result) {
timeRemainingUnbind();
$modalInstance.dismiss('cancel');
};
查看我正在工作的 fork plunker here
The code at this plnkr 有一个模式,当用户单击 "Click to take quiz" 按钮时会弹出一个模式,该按钮调用一个控制器方法,该方法又调用一个模式服务. 要使 plnkr 正常工作,请单击代码中的任意位置并按 space 栏以不影响语法的方式添加白色 space。这将触发 plnkr 重新初始化应用程序,并在您单击按钮后弹出模式。
问题是当 timeLeft
变量倒计时时,模态中打印的文本不会动态更新。而且,用户的按钮点击不会更新 quizAnswer
变量。简而言之,模式无法与调用控制器和视图进行交互。
需要对plnkr做哪些具体的改动才能让模态文本显示动态倒计时,让模态按钮改变$scope.quizAnswer变量的值?
另外,我一直在仔细阅读the documentation at this link。我认为答案可能与以下内容有关:
1.) 在 open(options)
中传递的 $uibModal
的 options
参数包含参数 scope
,它定义了用于模态内容的父范围,并且还有 属性 bindToController
,当设置为 true
时,将 scope
属性 绑定到 controllerAs
定义的特定控制器。
2.) open(options)
方法returns模态实例,其中包括close(result)
和dismiss(reason)
。
我怀疑解决方案在于这些方法和参数,但我正在寻找很好的例子,希望有经验的人能看到这个问题。
注意:这个问题的解决方案出现在已接受答案下方的评论中,尤其是 link 到另一个包含 2 行代码的帖子,用于将模态按钮点击的结果发回父控制器。
您有很多问题。
首先,navigation.js - 第 16 行的 takeQuiz
应该附加到 $scope
,而不是 this
,因为 this
会根据上下文发生变化.
其次,navigation.js 处的 $scope.$apply
和 $scope.$digst();
- 第 29/30 行是不必要的,因为您已经处于摘要循环中。它们应该被删除,否则它们会触发错误。
最后(这是您问题的核心),您误解了在创建模态实例时如何绑定模态选项。它不是双向绑定;它是从一个对象到另一个对象的单一扩展。因此,尝试绑定到选项(或创建带有 timeRemaining 的串联字符串)将不会在绑定后更新。
相反,一种可能性是在模态内部创建一个事件处理程序并在每次更新时广播,更新模态。此外,如果将正文文本作为前置和附加文本传递,则插入时间戳值会更容易:
您需要在您的导航控制器中注入(并从中广播)$rootScope
,因为 modalService
已在作用域链中非常高的位置注册。
在每个滴答声中,广播剩余时间 navigation.js:
$rootScope.$broadcast('timeRemainingTick', $scope.timeRemaining);
在您的 modalService.js 中,注册以接收控制器分配中的事件:
var timeRemainingUnbind = $scope.$on('timeRemainingTick', function(event, newTick) {
$scope.modalOptions.timeRemaining = newTick;
});
最后,确保通过在模态的关闭事件中调用 timeRemainingUnbind()
来解除事件绑定,以防止内存泄漏:
$scope.modalOptions.ok = function (result) {
timeRemainingUnbind();
$modalInstance.close(result);
};
$scope.modalOptions.close = function (result) {
timeRemainingUnbind();
$modalInstance.dismiss('cancel');
};
查看我正在工作的 fork plunker here