从指令中的控制器访问值

时间:2014-06-17 04:48:06

标签: angularjs

我会把我的代码放进去,然后我会解释我想要完成的事情。

我的指示:

chat.directive('autoScroll', function($timeout) {
    return {
        restrict: 'A',
        scope: {
            totalHeight: '='
        },
        link: function(scope, element, attrs) {
            var parent = element.parent('div.chat-text');
            $timeout(function() {
                scope.totalHeight += element.height();
            }, 0);
            parent.scrollTop(scope.totalHeight);
        }
    };
});

我在调用指令的地方:

<div id={{$index}} class='chat-window' ng-class='{active: chat.selected == true}' ng-click='selectChat($index)' ng-repeat='chat in chatWindows track by $index' resize-chat draggable='true' ondragstart='dragStart(event)'>
    <span class='title'>{{chat.name}}<i class='fa fa-times pull-right click' ng-click='remove(chatWindows, $index)'></i></span>
    <div class='chat-text'>
        <div class='message' ng-repeat='message in chat.messages' auto-scroll totalHeight='chat.totalHeight'>
            <span class='name'>{{message.user}}</span>
            <span class='time'>{{message.time}}</span>
            <p>{{message.message}}</p>
        </div>
    </div>
</div>

在div.message上调用该指令。 chatWindows对象以及我尝试访问的对象的概念如下:

$scope.chatWindows = [];
$scope.chatWindows.push({name: name, selected: true, totalHeight: 0, messages:[]});

所以,现在我想要完成的事情。当消息被添加到chatWindow对象时,我想获得该消息的高度,将其添加到chatWindow对象的总高度,然后将滚动条移动到该位置。

目前正在发生的事情是我收到错误&#34; Expression&#39; undefined&#39;用于指令&#39; autoScroll&#39;是不可转让的!&#34;。

我是一个全新的角色,目前正试图绕过指令,但很难找到如何解决这个问题。

2 个答案:

答案 0 :(得分:1)

通过在指令定义对象中使用scope属性,您已为该指令创建了一个独立的作用域。您希望从父作用域中获得的任何内容必须通过html中的属性向下传递。

您可能希望使用{{chat.totalHeight}}

插值

我无法理解为什么插值不会进入你的孤立范围,但是如果ngRepeat指令让你感到悲伤,请尝试将你的指令放在重复的元素中。

<div id={{$index}} class='chat-window' ng-class='{active: chat.selected == true}' ng-click='selectChat($index)' ng-repeat='chat in chatWindows track by $index' resize-chat draggable='true' ondragstart='dragStart(event)'>
<span class='title'>{{chat.name}}<i class='fa fa-times pull-right click' ng-click='remove(chatWindows, $index)'></i></span>
<div class='chat-text'>
    <div class='message' ng-repeat='message in chat.messages'>
      <div auto-scroll totalHeight='{{chat.totalHeight}}'
        <span class='name'>{{message.user}}</span>
        <span class='time'>{{message.time}}</span>
        <p>{{message.message}}</p>
      </div>
    </div>
</div>

或者抛弃孤立的范围(不要同时做这两件事):

chat.directive('autoScroll', function($timeout) {
return {
    restrict: 'A',
    link: function(scope, element, attrs) {
        var parent = element.parent('div.chat-text');
        $timeout(function() {
            scope.chat.totalHeight += element.height();
        }, 0);
        parent.scrollTop(scope.chat.totalHeight);
    }
};
});

要回答关于何时我们想要隔离范围的问题,您通常希望您的指令与范围无关,因此您可以在应用程序的任何位置使用相同的指令,而不管其父作用域。事实上,这通常是您想要做的事情。例如,只有当父作用域具有chat.totalHeight属性时,才能使用此指令(没有隔离的作用域)。不太可重复使用。

答案 1 :(得分:0)

总体上可能没有定义totalHeight的可能性 - 我过去遇到的一些异步问题。您可以尝试添加观察程序以确保正确定义。

chat.directive('autoScroll', function($timeout) {
    return {
        restrict: 'A',
        scope: {
            totalHeight: '='
        },
        link: function(scope, element, attrs) {
            var parent = element.parent('div.chat-text');
            scope.$watch('totalHeight', function() {
               console.log(scope.totalHeight); //Not necessary but interesting to see what is going on
               if(!!scope.totalHeight) {              
                 scope.totalHeight += element.height();
                 parent.scrollTop(scope.totalHeight);
               }
        }
    };
});

也许这可以解决你的问题,但我知道我过去遇到过类似的问题 - 我对这段代码的工作方式并不完全满意,感觉有点hacky,但除非别人知道如何获得围绕这个范围问题。$ watch这代表我...