Ответ 1
Ничего подобного с этим я знаю.. это лучшее, что я мог сделать:
<h1>{{city}}</h1>
<p ng-repeat="c in [coords.or.possibly.deeper.in.tree]">
Latitude: {{c.latitude}},
Longitude: {{c.longitude}}
</p>
Я только что переключился с KnockoutJS на AngularJS, и я не смог найти KnockoutJS с "привязкой данных в AngularJS".
Вот фрагмент кода в KnockoutJS. Связывание "с" создает новый контекст привязки, поэтому элементы-потомки связаны в контексте указанного объекта.
<h1 data-bind="text: city"> </h1>
<p data-bind="with: coords">
Latitude: <span data-bind="text: latitude"> </span>,
Longitude: <span data-bind="text: longitude"> </span>
</p>
<script type="text/javascript">
ko.applyBindings({
city: "London",
coords: {
latitude: 51.5001524,
longitude: -0.1262362
}
});
</script>
Есть ли у AngularJS что-то вроде контекста?
Ничего подобного с этим я знаю.. это лучшее, что я мог сделать:
<h1>{{city}}</h1>
<p ng-repeat="c in [coords.or.possibly.deeper.in.tree]">
Latitude: {{c.latitude}},
Longitude: {{c.longitude}}
</p>
Создайте настраиваемую директиву, которая пересекает исходный объект и создает соответствующие свойства в области директивы, которые являются ссылками getter/setter к исходному объекту.
Проверьте этот plunker.
angular.module('koWith', [])
.directive('koWith', function () {
return {
controller: function ($scope, $attrs) {
var withObj = $scope.$parent[$attrs.ngWith];
function getter(prop) {
return this[prop];
}
function setter(val, prop) {
this[prop] = val;
}
for (var prop in withObj) {
if (withObj.hasOwnProperty(prop)) {
Object.defineProperty($scope, prop, {
enumerable: true,
configurable: true,
get: getter.bind(withObj, prop),
set: setter.bind(withObj, prop)
});
}
}
},
restrict: 'A',
scope: true
};
});
angular.module('myApp', [])
.controller('myController', function ($scope) {
$scope.customer = {
name: "Timmeh",
address: {
address1: "12 S Street",
address2: "",
city: "South Park",
state: "CO",
zipCode: "80440"
}
};
});
<div ko-with="customer">
<h2>{{name}}</h2>
<div ko-with="address">
{{address1}}<br>
{{address2}}<br>
{{city}}, {{state}} {{zipCode}}
</div>
</div>
В KnockoutJS привязки сохраняют привязкуКонтекст и данные разделены, поэтому создание привязки with
тривиально, так как ему нужно только создать новый дочерний bindingContext из текущего и использовать объект with
в качестве его значения данных.
В AngularJS область действия директивы - это, в основном, bindingContext и объект данных, свернутый в один. Когда создается новая область, чтобы получить поведение with
, свойства объекта with
должны быть привязаны к вновь созданному объекту области видимости.
Вот решение, основанное на @nwayve, но оно поддерживает выражения в koWith, а также наблюдает за обновлением свойства/выражения, указанного в koWith:
.directive('koWith', function () {
return {
restrict: 'A',
scope: true,
controller: function ($scope, $attrs, $parse) {
var ScopePropertyDesc = function (prop) {
var self = this;
self.propName = prop;
self.parsed = $parse(prop);
self.enumerable = true;
self.configurable = true;
//self.writable = true;
self.get = function () {
var withObj = $scope.$parent[$attrs.koWith];
var res = self.parsed($scope.$parent, withObj);
return res;
};
self.set = function (newValue) {
var withObj = $scope.$parent[$attrs.koWith];
self.parsed.assign(withObj, newValue);
};
};
$scope.$parent.$watch($attrs.koWith, function (oldVal, newVal) {
var withObj = $scope.$parent[$attrs.koWith];
(function copyPropertiesToScope(withObj) {
for (var prop in withObj) {
if (withObj.hasOwnProperty(prop)) {
Object.defineProperty($scope, prop, new ScopePropertyDesc(prop));
}
};
})(withObj);
});
}
};
});