当范围改变时,视图中的angularjs变量不会改变

时间:2013-08-09 22:33:03

标签: angularjs

我是AngularJS的新手。但我有一个严重的问题。在过去的48小时里,我一直被困在这一点上。现在我的问题是:

即使我更新控制器中的变量,我的视图也不会更新。这是代码。

var stData;
function mainCtrl($scope,$http){

retrieveDataset($scope,$http,  'http://localhost:8080/ramap-service/DataProvider?title='+$scope.title+'&year='+$scope.year);  

$scope.$apply($scope.changeMap = function(){          
    var curl = 'http://localhost:8080/ramap-service/DataProvider?title='+$scope.title+'&year='+$scope.year;
    console.log(curl);        
    showDialog();
    retrieveDataset($scope,$http,curl);                              
});
function retrieveDataset($scope,$http, curl){
 $http.get(curl).success(function (data,status){        
     console.log(data.description); 
     $scope.desc = data.description;
     loadColors(data.results);
     stData=data.results;
     handleKeys($scope,data.results);        
 }).error(function(data,status){
     console.log(data);
 });
}

}

function loadColors(data){
var paths = document.getElementsByTagName('path');
for(var i=0;i<data.length;i++){        
    for(var j=0;j<paths.length;j++){
        var path = paths[j];
        if(data[i][4]===path.id){                 
            path.style.fill=getColor(data[i][5],data);                
            break;
        }
    }
}
}

function getColor(amount, data){
var color;    
var segments = segmentThem(data);
if(amount<=segments[1]){
    color = '#FFE5E9';
}else if(amount<segments[2]){
    color = '#FF657B';
}else if(amount < segments[3]){
    color = '#B20019';
}else if(amount < segments[4]){
    color = '#4C000B';
}else if (amount<segments[5]){
    color = '#FFB1BC';
}else if (amount <segments[6]){
    color = '#7E0012';
}else{
    color = '#FE0024';
}
return color;              
}

function segmentThem(data){
var min = findMin(data);
var max = findMax(data);
var diff = max - min;
var interval =diff/7;    
interval = Math.round(interval);
interval = roundSpecially(interval);    
var amounts = new Array();
for(var i=0;i<7;i++){
    if(i===0){
        amounts[i]=min;
        continue;
    }
    var prev = parseInt(i)-1;
    amounts[i] = amounts[prev]+interval;

}
return amounts;
}

function findMin(data){  
var least =Number(data[0][5]);
for(var i=0;i<data.length;i++){
    var num = Number(data[i][5]);
    if(num<least){
        least=num;
    }
}
return least;
}

function findMax(data){
var max = Number(data[0][5]);
for(var i=0;i<data.length;i++){
    var num = Number(data[i][5]);
    if(num>max){
        max=num;
    }
}
return max;
}

function handleKeys($scope,data){
var segments = segmentThem(data);
var result = new Array();
var denom = 0;
if((segments[4]/1000000000)>0.99){
    denom = 1000000000;
}else if ((segments[4]/1000000)>0.99){
    denom = 1000000;
}else if((segments[4]/1000)>0.99){
    denom = 1000;
}else{
    denom = 100;
}
for(var i=0; i<segments.length;i++){
    result[i] = segments[i]/denom;
}       
$scope.denom = denom;
$scope.results = result;
}

function roundSpecially(num){
num = num+'';
var length = num.length-1;
var re = num[0];
for(var i=0; i<length;i++){
    re=re+'0';
}
return Number(re);
}

function showInfo(){
var event = window.event;
var element = event.srcElement;
var data = getData(element.id);    
document.getElementById('info').innerHTML= '<b>'+data[3]+'</b>'+"<br>"+currency('N', data[5]);   
}

function getData(id){  
var result;
for(var i=0;i<stData.length;i++){
    if(id===stData[i][4]){
        result = stData[i];                        
    }
}
if(typeof result === 'undefined'){
    return alert("This program has some undefined values on line 224");
}else{
    return result;
}  

}

function currency(sSymbol, vValue) {
 vValue = Number(vValue);
 var aDigits = vValue.toFixed(2).split(".");
 aDigits[0] = aDigits[0].split("").reverse().join("").replace(/(\d{3})(?=\d)/g,  "$1,").split("").reverse().join("");
  return sSymbol + aDigits.join(".");
 }

function showDialog(){
 var el = document.getElementById("myOverlay");
  el.style.visibility = (el.style.visibility==='hidden')?'visible':'hidden';
}

然后我的观点是这样的:

<div id="container" ng-controller="mainCtrl">
<header>
    <img src="img/header3.png"/>
</header>
<aside >
    <h5 >About the Current dataset</h5>
    <p class="points" >Title</p>    
          {{title}} {{year}}
    <p class="points">Description</p>
        {{desc}}
</aside>
<div  id="colorcode" >
    <h5>Map key</h5>
   ({{denom|currency:"N"}})
<table >
  <tr>
    <th>Color</th>
    <th>Range</th>
  </tr>
  <tr>
    <td style="background:#FFE5E9;"></td>
    <td >{{results[0]}} - {{results[1]}}</td>
  </tr>
  <tr>
    <td  style="background:#FF657B;"></td>
    <td >{{results[1]}} - {{results[2]}}</td>
  </tr>
  <tr>
    <td style="background:#B20019"></td>
    <td >{{results[2]}} - {{results[3]}}</td>
  </tr>
  <tr>
    <td style="background:#4C000B"></td>
    <td>{{results[3]}} - {{results[4]}}</td>
    <tr>
    <td style="background:#FFB1BC;"></td>
    <td>{{results[4]}} - {{results[5]}}</td>
  </tr>
  <tr>
    <td style="background:#7E0012"></td>
    <td>{{results[5]}} - {{results[6]}}</td>
  </tr>
  <tr>
    <td style="background:#FE0024"></td>
    <td>Above {{results[6]}}</td>
  </tr>
</table>
</div>
<span onclick="showDialog()" id="editspan"><i class="icon-edit icon-2x"></i><input type="submit" name="button" id="button" value="Change Dataset"/></span>
<div id="info">    
</div>
<div id="map">      
    <svg  xmlns="http://www.w3.org/2000/svg" version="1.1" width="797" height="710" viewBox="0 0 297 210" >
  <style type="text/css">
    .state {fill:#FF0000; stroke:white ; stroke-width:0.5; stroke-opacity:1;}
  </style>

</svg>
</div>
<div id="myOverlay">
    <table id="dtable">

                          <tr id="row">
                            <td id="dtd"><form id="dialogue_box">
                        <div class="box1"><label id="label">Dataset title:</label></td>
                            <td id="dtd"> <select ng-model="title" value="budget works dataset">
                          <option value="budget works dataset" id="box" >Budget Works Dataset</option>                         
                        </select></td>
                          </tr></div>
                          <tr>
                            <td id="dtd"><div class="box1"><label id="label2">Specify Year: </td>
                            <td id="dtd"></label><select class="first" ng-model="year" >
                                <option value="2009">2009</option>
                          <option value="2010">2010</option>
                          <option value="2011">2011</option>
                          <option value="2012">2012</option>
                          <option value="2013">2013</option>                                                    
                        </select></td>
                          </tr></div>

                            <tr>
                                <td id="submit"><button id="button" ng-controller="mainCtrl" ng-click="changeMap()"> Enter</button><button id="button" onclick="showDialog()"> Cancel</button></td>
                            </tr>

                        </form></div>

                        </table>
</div>

但这些变量都没有变化。

2 个答案:

答案 0 :(得分:0)

如果正确缩进代码,您可以看到控制器只更新aside元素中的代码,而页面的其余部分不在MainCtrl的范围内。还有一些其他标签的顺序错误。此模板应该可以解决您的问题。

<div class="container" ng-controller="mainCtrl">
    <aside>
        <h5>
            About the Current dataset
        </h5>
        <p class="points">
            Title
        </p>
        {{ititle}} {{iyear}}
        <p class="points">
            Description
        </p>
        {{desc}}
    </aside>
    <div id="myOverlay">
        <table id="dtable">
            <tr id="row">
                <td id="dtd">
                    <form id="dialogue_box">
                        <div class="box1">
                            <label id="label">
                                Dataset title:
                            </label>
                        </div>
                    </form>
                </td>
                <td id="dtd">
                    <select ng-model="title" value="budget works dataset">
                        <option value="budget works dataset" id="box">
                            Budget Works Dataset
                        </option>
                    </select>
                </td>
            </tr>
            <tr>
                <td id="dtd">
                    <div class="box1">
                        <label id="label2">
                            Specify Year:
                        </label>
                    </div>
                </td>
                <td id="dtd">
                    </label>
                    <select class="first" ng-model="year">
                        <option value="2009">
                            2009
                        </option>
                        <option value="2010">
                            2010
                        </option>
                        <option value="2011">
                            2011
                        </option>
                        <option value="2012">
                            2012
                        </option>
                        <option value="2013">
                            2013
                        </option>
                    </select>
                </td>
            </tr>
            <tr>
                <td id="submit">
                    <button id="button" ng-controller="mainCtrl" ng-click="changeMap()">
                        Enter
                    </button>
                    <button id="button" onclick="showDialog()">
                        Cancel
                    </button>
                </td>
            </tr>
        </table>
    </div>
</div>

现在有一个带有ng-controller =“mainCtrl”标签的包含div,并且应该更新模板的其余部分,因为一切都在范围内。

答案 1 :(得分:0)

即使这是很多代码(你应该将其分解以缩小你的问题),但我分享了我的想法可能是什么问题。对不起,不要更精确,但你的例子很大,有很多陷阱。

您正在从网络服务器加载一些数据。当您得到该结果时,您将检索到的数据写入局部变量stData并调用结果处理程序中的其他一些函数,这似乎没问题。 但是在showInfo() { getData(){...} }函数中,您正在使用stData并期望它保留最新数据 - 这不能保证。

我建议您过度考虑检索数据的整体工作流程,并在结果处理程序中执行所有操作。将stData存储在$scope.stData中,这样angular就有机会了解您的传入数据。

此外,您在mainCtrl中引用了DOM,这绝不是一个好主意。使用DOM哭泣以实现指令。

我还建议您完成angular-phonecat教程http://docs.angularjs.org/tutorial/step_00,一旦完成,您可以根据自己的需要进行更改。你将学到很多东西,包括:

  • 将DOM操作分离为指令
  • 创建包含服务工厂的模块
  • $resource(用于服务电话)的使用
  • 注射用法
  • 更好地了解角度范围机制和$digest生命周期($ apply())

所以基本步骤是

  • 使用$ resource
  • 将服务调用分离到服务工厂
  • 将该服务注入您的Controller并进行通话。
  • 减少对dom的工作 - 不需要任何document.getElementById等;)
  • 将所有帮助函数移动到服务中,您可以将其称为toolService,并在Controller中注入该服务。

这会清理你的代码很多,每个部分都有责任,这有助于你在寻找错误。

快乐编码:)