Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在指令和控制器之间使用公共作用域_Javascript_Angularjs - Fatal编程技术网

Javascript 在指令和控制器之间使用公共作用域

Javascript 在指令和控制器之间使用公共作用域,javascript,angularjs,Javascript,Angularjs,我想创建一个svg形状,它是一个圆,并从html文档中存在的应用程序范围中读取规范,例如半径或中心坐标: <div ng-app="myApp" > <div id="body" ng-controller="testCtrl"> cx: <input type="number" ng-model="cx"/><br/> cy: <input type="number" ng-model="cy"/><br/&g

我想创建一个svg形状,它是一个圆,并从html文档中存在的应用程序范围中读取规范,例如半径或中心坐标:

<div ng-app="myApp" >
<div id="body"  ng-controller="testCtrl">
    cx: <input type="number" ng-model="cx"/><br/>
    cy: <input type="number" ng-model="cy"/><br/>
    R : <input type="number" ng-model="radius" />

    <draggable-circle/>
</div>
</div>
该指令是:

 testCtrl.directive('draggableCircle', function () {
       function link(scope, el, attr) {
        var w = 600, h = 400;
        var drag = d3.behavior.drag().origin(Object).on("drag", dragmove);
           var svg = d3.select(el[0]).append("svg")
                        .attr("class", "svgContainer")
                        .attr("width", w)
                        .attr("height", h);
         var newg = svg.append("g").data([{ x: scope.cx , y: scope.cy}]);

         var dragCircle = newg.append("circle")
                        .attr("r", scope.radius)
                        .attr("cx", function(d) {
                            return d.x;
                        })
                        .attr("cy", function (d) {
                            return d.y;
                        })
                        .attr("fill", "red")
                        .style("fill-opacity", 0.8)
                        .style("stroke", "steelblue")
                        .style("cursor"," pointer")
                        .call(drag);
         function dragmove(d) {
            var mousePosition = d3.mouse(this);
           dragCircle.attr("cx", d.x =scope.cx= mousePosition[0])
               .attr("cy", d.y=scope.cy = mousePosition[1]);
                        scope.$apply()
         }
       }
         return {
                    link: link
                };
     });
问题是,当控制器更改坐标值时,必须在指令中更改形状。但它并没有像我预期的那样起作用。此外,当用户拖动形状时,指令中更改的值会自动广播到控制器和模型,因为使用了
scope.$apply()
,我认为这不是最佳解决方案。 我想进行双工连接,即当指令中的规范发生更改时,它会影响控制器,反之亦然。我还想为这个目标实施最好的解决方案

Plunker链接:

更新

我想将控件和形状绑定在一起,这意味着形状坐标会随着绑定到模型的控件值的更改而更改,反之亦然。

Saman

你可以使用这个概念叫做。它工作正常,是一个轻量级的解决方案。您无需过度使用
$watch
$broadcast
$emit

萨曼


你可以使用这个概念叫做。它工作正常,是一个轻量级的解决方案。您不需要过度使用
$watch
$broadcast
$emit
您的问题根本不是范围;问题是您将
dragmove
函数注册为回调函数。 此回调未在AngulasJs环境中注册,因此需要使用
$apply
。当此回调对范围变量进行更改时,除非调用
$apply
,否则angular框架不会意识到它。在使用非角度库和角度代码时,这是一个常见问题

我认为你是对的;也许你现在需要的只是

function updatePosition(){ 
    dragCircle.attr("cx", d.x =scope.cx)
           .attr("cy", d.y=scope.cy);
}

$scope.$watch('cx', updatePosition);
$scope.$watch('cy', updatePosition);

如果这方面有任何问题,请告诉我,因为我从未使用过d3.js,所以我可能不知道那里发生了什么事。

你的问题根本不是关于作用域;问题是您将
dragmove
函数注册为回调函数。 此回调未在AngulasJs环境中注册,因此需要使用
$apply
。当此回调对范围变量进行更改时,除非调用
$apply
,否则angular框架不会意识到它。在使用非角度库和角度代码时,这是一个常见问题

我认为你是对的;也许你现在需要的只是

function updatePosition(){ 
    dragCircle.attr("cx", d.x =scope.cx)
           .attr("cy", d.y=scope.cy);
}

$scope.$watch('cx', updatePosition);
$scope.$watch('cy', updatePosition);
如果这方面有任何问题,请告诉我,因为我从未使用过d3.js,所以我可能不知道那里发生了什么事情。

您应该阅读。在此之后,您需要从指令中的控制器中获取$watch属性,并在应用它们之后生成$scope.apply,这将不会导致父范围,因为对象位于隔离范围中

我为你做了一件事:


cx:

赛义德:
R: var angularApp=angular.module('myApp',[]); var testCtrl=angularApp.controller('testCtrl',function($scope){ $scope.initial={}; $scope.initial.cx=100; $scope.initial.cy=100; $scope.initial.radius=50; }); 指令('DragableCircle',函数(){ 功能链接(范围、el、属性){ var w=600,h=400; var drag=d3.behavior.drag().origin(Object).on(“drag”,dragmove); var svg=d3.select(el[0]).append(“svg”) .attr(“类”、“svgContainer”) .attr(“宽度”,w) .attr(“高度”,h); var newg=svg.append(“g”).data([{x:scope.initial.cx,y:scope.initial.cy}]); var dragCircle=newg.append(“圆”) .attr(“r”,范围初始半径) .attr(“cx”,功能(d){ 返回d.x; }) .attr(“cy”,函数(d){ 返回d.y; }) .attr(“填充”、“红色”) .style(“填充不透明度”,0.8) .风格(“笔划”、“钢蓝”) .style(“光标”、“指针”) .呼叫(拖动); 范围$watch('initial.cx',applyNewProperties); 范围:$watch('initial.cy',applyNewProperties); 函数applyNewProperties(){ dragCircle.attr(“cx”,scope.initial.cx) .attr(“cy”,scope.initial.cy); } 功能拖动(d){ console.log(scope.initial); var mousePosition=d3.mouse(this); dragCircle.attr(“cx”,d.x=scope.cx=scope.initial.cx=mousePosition[0]) .attr(“cy”,d.y=scope.cy=scope.initial.cy=mousePosition[1]); 范围:$apply() } } 返回{ 链接:链接, 范围:{ 首字母:'=' } }; });
你应该读一读。在此之后,您需要从指令中的控制器中获取$watch属性,并在应用它们之后生成$scope.apply,这将不会导致父范围,因为对象位于隔离范围中

我为你做了一件事:


cx:

赛义德:
R: var angularApp=angular.module('myApp',[]); var testCtrl=angularApp.controller('testCtrl',function($scope){ $scope.initial={}; $scope.initial.cx=100;
scope.$watch('coord', updateCoord,true);

function updateCoord() {
      dragCircle.attr("cx", scope.coord.cx)
        .attr("cy", scope.coord.cy).attr("r",scope.coord.radius);
 }


function dragmove(d) {
    var mousePosition = d3.mouse(this);
    dragCircle.attr("cx", d.x  = scope.coord.cx = mousePosition[0])
         .attr("cy", d.y =  scope.coord.cy =mousePosition[1]);
                scope.$apply();
 }
 function update() {
    dragCircle = newg.selectAll("circle")
                .attr("r", scope.data.radius)
                .attr("cx", scope.data.cx)
                .attr("cy", scope.data.cy)
                .call(drag);
 }