poniedziałek, stycznia 12, 2015

Polymeryzacja AngularJS ;-)

Polymer mi się bardziej podoba od AngularJS, ale w ramach zabawy spróbowałem dziś w jakiś sposób zasymulować data-binding Polymerowy między custom-elementami w AngularJS.

Ten z AngularJS jest niezły, ale nie działa do końca tak jak bym chciał.
Tzn. sam data-binding działa tak jak bym chciał, ale już w samych dyrektywach AngularJS informacje o zmianie wartości atrybutów nie są propagowane same z siebie, trzeba się na nie zarejestrować.

A chciałbym mieć w kodzie strony:

<geo-emiter lat="lat" lon="lon"></geo-emiter>
<today-temperature lat="lat" lon="lon"></today-temperature>


gdzie geo-emiter powinno wyemitować geolokalizację, a today-temperature powinno na tej podstawie wyświetlić temperaturę.

W Polymerze to by było proste, w AngularJS na razie udało mi się doprowadzić do czegoś takiego:

app.directive("geoEmiter",["geolocation", "$log", function(geolocation, $log) {
return {
scope: {
lat: "=",
lon: "="
},
controller: function($scope) {
geolocation.getLocation().then(function(data) {
var coords = {lat:data.coords.latitude, lon:data.coords.longitude};
$scope.lat = coords.lat;
$scope.lon = coords.lon;
});
}
}
}]);

app.directive("todayTemperature", ["geolocation", "$http", "$log", "$interval", function(geolocation, $http, $log, $interval) {
return {
restrict: "E",
template: "<h1>{{temperature}}</h1><h4>{{minTemp}}/{{maxTemp}}</h4>",
scope: {
lat: "=",
lon: "="
},
controller: function($scope) {
$scope.$watch(function() { return $scope.lat}, function(val) {
if (!val) return;
$scope.temperature = "";
var url = "http://api.openweathermap.org/data/2.5/weather?lat="+$scope.lat+"&lon="+$scope.lon;
$log.log(url);
var convert = function(x) {
return Math.round((x-273.15)*10)/10.0;
}
$http.get(url).success(function(data) {
$log.log(data);
$scope.temperature = convert(data.main.temp);
$scope.minTemp = convert(data.main.temp_min);
$scope.maxTemp = convert(data.main.temp_max);
});
});
}
}
}]);


Ten $watch jest trochę ohydny, bo tutaj to co dostajemy w Polymerze od strzału, tutaj trzeba udawać.

Pierwsza dyrektywa geo-emiter po prostu w momencie gdy otrzyma od geolocation lokalizację to emituje ją na zewnątrz, w today-temperature musi być $watch, który "słucha" czy aby wartość w lat się nie zmieniła, jeśli się zmieniła to odpala cały kod do pobrania pogody z OpenWeatherMap :-) [dzięki wspaniałemu nagłówkowi Access-Control-Allow-Origin:* można sobie pogadać z tymi serwerami z dowolnej strony z AJAXem :-)].


Podobne postybeta
Data binding w Polymerze jest oszukany ;-)
Najkrótsza droga do przyszłości - Polymer ;-)
Automagiczne dodawanie tagów do Pocket :-)
Bayesian Inference Tool jako Chrome App ;-)
Airly + Python + Oczyszczacz Powietrza = lepsze oddychanie ;-)