2013-07-30 103 views
1

我正在实现一个解决方案,用于聚焦元素,建议here。 它适用于html输入,但不适用于自定义指令。这里是the plunk来演示这个问题。点击页面加载时的“焦点输入”将焦点放在按钮旁边的文本输入中,但单击“焦点控件”不会将焦点输入放在旁边。其实,原因是当点击“焦点控制”按钮(可以在浏览器控制台中看到)时,不会调用$watch函数。angularjs使用指令作为另一个指令的属性

问题是为什么$watch函数没有被调用?

的JavaScript

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

app.controller('MainCtrl', function($scope) { 
    $scope.name = 'World'; 
    $scope.inputFocused = false; 
    $scope.controlFocused = false; 
}); 

app.directive('focusedWhen', function() { 
    return { 
    restrict: 'A', 
    link: function (scope, element, attrs) { 
     scope.$watch(attrs.focusedWhen, function (value) { 
     console.log('focusedWhen', value); 
     if (value) { 
      element.find('input[type=text]').andSelf().trigger('focus'); 
     } 
     }); 
    } 
    }; 
}); 
app.directive('myControl', function() { 
    return { 
    restrict: 'E', 
    scope: {}, 
    template: '<span><input type="text"></span>', 
    link: function (scope, element, attrs) { 

    } 
    }; 
}); 

HTML

<!DOCTYPE html> 
<html ng-app="plunker"> 

    <head> 
    <meta charset="utf-8" /> 
    <title>AngularJS Plunker</title> 
    <script>document.write('<base href="' + document.location + '" />');</script> 
    <link rel="stylesheet" href="style.css" /> 
    <script data-require="[email protected]*" data-semver="1.7.2" src="http://code.jquery.com/jquery-1.7.2.min.js"></script> 
    <script data-require="[email protected]" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js" data-semver="1.0.7"></script> 
    <script src="app.js"></script> 
    </head> 

    <body ng-controller="MainCtrl"> 
    <p>Hello {{name}}!</p> 
    <div> 
     <button ng-click="inputFocused = true;">Focus input</button> 
     <input type="text" focused-when="inputFocused" /> 
    </div> 
    <div> 
     <button ng-click="controlFocused = true;">Focus control</button> 
     <my-control focused-when="controlFocused"></my-control> 
    </div> 
    </body> 

</html> 

回答

1

看起来问题是您的手表$未触发,因为该值仍真正在随后的点击。你有的问题是,你的重点只能在一个输入。因此,所有按钮/输入对都需要知道如何将他们自己的“重置”为假,当他们的同伴之一被点击对焦时。我会做相反的事情 - 设置获取焦点的指令的真实值,而不是真正的值触发焦点。您可以创建一种新的指令来监听点击(比如如何单击工作),然后遍历指令的子节点以找到触发其焦点的输入。此相同的指令可以在其link()有一个“模糊”事件要知道它的布尔值设置为false(即controlFocusinputFocus)。

编辑您的指令myControl创建了一个隔离作用域,当您为其指定作用域时:{}。从this

在“分离物”范围从正常范围的不同点在于它不 prototypically从父范围继承。这在 创建可重用组件(不应该意外读取)或 修改父范围中的数据时非常有用。当你将{}的范围

所以controlFocus不存在。

+0

我相信这个问题与随后的点击无关。问题是即使第一次点击“焦点控制”按钮,$ watch功能也不会启动。在第一次点击之前,控制器中的值为false。所以至少第一次点击它应该会触发。 你可以请你展示你的方式来解决这个问题在一个蹲/小提琴/任何? –

+0

忘记了我在查看代码时进行了更改。我从你的自定义指令中删除了范围,因为它创建了一个新的隔离范围。然后,我添加了'replace:true',以便预期的标记代替它。现在,从您的自定义指令派生的输入将获得焦点。 PLUNKER:http://plnkr.co/edit/ClrLRV49UG3klbA9fAww?p=preview – mitch

+0

好的,当'scope:false'被设置时它确实有效。它在'scope:true'设置时起作用。即使设置了'replace:false',它也可以工作(看起来像'replace'不会影响任何东西)。但是,不幸的是,当scope:{}被设置(隔离范围)时,它不起作用。 您能否更新您的答案以清楚说明问题的原因:使用隔离范围?所以我可以接受它。 P.S.也许,分叉是个更好的选择。因为现在对其他观众来说这个问题是不是很清楚。 –

相关问题