2013-05-27 41 views
1

我有一個稱爲addressesForUser的地址數組。我也有一個隔離範圍的「地址」指令。打印時分析角度值,但不是指令屬性

當我這樣做:

<div ng-repeat="add in addressesForUser" entryid="{{ add.id }}">{{ add.id }}</div>    

一切都很好,和三個地址,我得到以下生成的html:

<div entryid="1">1</div> 
<div entryid="2">2</div> 
<div entryid="3">3</div> 

,但是當我這樣做:

<address ng-repeat="add in addressesForUser" entryid="{{ add.id }}"></address> 

然後嘗試console.log(attrs.entryid)內的指令的鏈接功能,我得到「add.id」作爲輸出中的字符串。更糟的是,生成的html中的屬性是未定義的 - 只有屬性名稱存在 - 所以它既不是1到3的數字,也不是字符串「add.id」。

我在做什麼錯?最終目標是讓每個地址指令都在其entryid屬性中讀取,因此它可以自動填充並生成地址卡,或者如果缺少entryid,它將顯示一個表單以輸入新地址。後一部分工作正常,但我不明白爲什麼它不讀取入口值。

編輯:當我不使用隔離作用域(即從指令中刪除「scope:{}」)時,它可以工作。但是我需要隔離範圍,所以我想我只需要一種方法來讓屬性包含在單個指令的範圍內。這裏有一個簡單的地址指令代碼:

myapp.directive('address', ['GeoService', '$http', function (gs, http) { 
    return { 
     restrict: 'E', 
     templateUrl: 'address.html', 
     scope: { 
     }, 
     link: function (scope, element, attrs) { 

      scope.emptyForm = { 
       first_name: '', 
       last_name: '', 
       country: '', 
       city: '', 
       street: '', 
       phone: '', 
       is_def: '', 
       zip: '', 
       additional_info: '', 
       residence_type: '' 
      } 

      console.log(attrs.entryid); 

      scope.countries = gs.countries(); 
      scope.resetAddressForm = function(e) { 
       scope.newAddressForm = scope.emptyForm; 
      } 
      scope.saveAddress = function() { 
       http.post('/users/saveaddress', scope.newAddressForm).then(function (response) { 

        console.log(response.data); // Do something 
       }); 
      } 
      scope.$watch('newAddressForm.country', function(v) { 
       if (v != undefined) { 
        scope.cities = gs.cities(v); 
       } 
      }); 
     } 
    } 
}]); 
+0

我認爲你需要發佈你的地址的指令代碼,更好地理解這個問題,一個[plunker ](plnkr.co/edit /)例子會更好,無論如何,我認爲這是因爲隔離,有什麼問題,沒有看到指令的代碼,我不知道。 –

+0

用指令代碼更新原始文章。這是隔離範圍,它可以工作,如果我刪除隔離,但在這種情況下,我需要它。 – Swader

+0

正如你在答案中所說的解決方案'範圍:{entryid:'='}',但這就是如果你打算在模板中使用它,鏈接函數是[@Josh David Miller](http:///stackoverflow.com/users/259038/josh-david-miller)在他的回答中說。 –

回答

1

由於您的指令不會修改add.id的值(因此您不需要雙向數據綁定),所以我建議使用@而不是=。一旦與@定義,你可以使用attrs.$observe()scope.$watch()得到插值:

scope: { 
    entryid: '@', 
}, 
link: function (scope, element, attrs) { 
    attrs.$observe('entryid', function(value) { 
     console.log('observed value=',value); 
    }); 
    scope.$watch('entryid', function(value) { 
     console.log('watched value=',value); 
    }); 
    ... 
} 

fiddle

+0

希望這是在文檔中的_anywhere_。 Egghead也不太好。感謝您的解釋。 – Swader

0

經過一些更多的修補之後,我得到了意外的解決方案。文檔可以真正在這方面使用更多的工作。

本質上,該分離物範圍需要被定義爲這樣:

scope: {entryid: "="} 

,然後將值通過範圍訪問,不經由ATTRS,如在

console.log(scope.entryid); 
2

這裏的問題實際上是在指令不能假定運行link函數時屬性已準備就緒。如果該值是插值的,它通常對您而言不可用。訪問屬性的典型方式是通過$observe

link: function (scope, element, attrs) { 
    attrs.$observe('entryid', function (val) { 
    // do something with the val 
    }); 
} 

如果您使用的是分離的範圍,它可能是一個好主意,增加對公共屬性作用域屬性,但你還是不應該假設值爲在link期間可用。如果值可能需要插值,則應始終使用$observe方法。

+0

有趣。當我嘗試重新格式化我的指令以使用像您所說的觀察時,雖然它不會插值。 'console.log(val)'給我add.id,字符串,而不是實際的值,並且{{add.id}}也作爲一個文字字符串返回。是什麼賦予了? – Swader

+0

你必須發佈一個Plunker,因爲這應該普遍工作。 –