Bilateral binding with get and Form URL parameters (parameters and slider)

Currently, I can get GET parameters using $location.$$search .

However, I still don't know how to do 2-way binding for URL and FORM in the following case.

As the following demo, when the user updates the FORM elements, the corresponding URL should be: https://lazyair.co/en/user/quick_search/index#?from=TOKYO&to=TAIPEI&depart=2016/06/03~2016/06/06&return=2016/06/08~2016/06/11&chart_type=column&depart_slider=10:00~24:00

inline

Demo page: https://lazyair.co/en/user/quick_search/index

Sliderbar Directive JavaScript Code

  'use strict'; quick_search_app.directive('ionslider',function($timeout){ var get_hour_minute, getHHMMformat, isDepartureAtInInterval; get_hour_minute = function(value) { var hours, minutes; hours = Math.floor(value / 60); minutes = value - (hours * 60); if (hours.length === 1) { hours = '0' + hours; } if (minutes.length === 1) { minutes = '0' + minutes; } return [hours, minutes]; }; getHHMMformat = function(values) { var hours, minutes; hours = values[0].toString(); minutes = values[1].toString(); if (hours.length === 1) { hours = '0' + hours; } if (minutes.length === 1) { minutes = '0' + minutes; } return hours + ':' + minutes; } isDepartureAtInInterval = function(departure_at, slider){ var t = new Date(Date.parse(departure_at)) var HHMM_in_minutes = t.getUTCHours()*60 + t.getMinutes(); return slider.from <= HHMM_in_minutes && slider.to >= HHMM_in_minutes; } var updateFlighSeries = function(slider, flight_series) { $.each(flight_series, function() { var current_series = this; angular.forEach(current_series.data, function(value, key) { if(isDepartureAtInInterval(value.departure_at, slider)){ this.visible = true ; }else{ this.visible = false ; } }, current_series); }); } return{ restrict:'AE', scope: false, controller: 'quick_search_ctrl', link:function(scope, element, attr, ctrl){ $(element).ionRangeSlider({ hide_min_max: true, keyboard: true, min: 0, max: 1440, from: 0, to: 1440, type: 'double', step: 30, prefix: "", chartConfig: element.attr("chart-config"), grid: true, prettify: function (value) { return getHHMMformat(get_hour_minute(value)); }, onChange: function(slider) { var _this = this; updateFlighSeries(slider, scope[_this.chartConfig].series) angular.forEach(scope.chart_names, function(chart_cfg_name){ scope.$apply(function () { scope.lowestFlights[chart_cfg_name] = angular.copy(scope.filterLowestPrice(scope[chart_cfg_name])) console.log(scope.lowestFlights[chart_cfg_name]) }); }, scope) } }); } } }); 

HTML

 <ui-select.selectpicker{:theme => "select2", "ng-disabled" => "disabled", "ng-model" => "from", :name => "from", :theme => "select2", "ng-change"=>"updateDeparture(from)", :style => "width: 200px;", :required => "" } <ui-select-match{ "ng-cloak"=>"", :placeholder => t("from") } {{$select.selected.t_name}} {{$select.selected.name}}</ui> </ui> <ui-select.selectpicker{"ng-disabled" => "disabled", "ng-model" => "to", :name => "to", :theme => "select2", "ng-change"=>"updateArrival(to)", :style => "width: 200px;", :required => ""} <ui-select-match.selectpicker{"ng-cloak"=>"", :placeholder => t("to")} {{$select.selected.t_name}} {{$select.selected.name}}</ui> <ui-select-choices{:repeat => "node in arrivals | filter: $select.search" } <span ng-bind-html="node.t_name | highlight: $select.search"></span> <span ng-bind-html="node.name | highlight: $select.search"></span> </ui> </ui> 

url parameters were cleared in the loop $rootScope.Scope#$digest

inline

I put a breakpoint inside $locationChangeSuccess and found that the url parameters were cleared in the $rootScope.Scope#$digest loop

 app.run(function ($rootScope) { $rootScope.$on('$locationChangeSuccess', function () { debugger console.log('$locationChangeSuccess changed!', new Date()); }); }); 

Two-way binding not working with directive

Two-way binding not working with the directive, Actually two-way binding works on View, but does not work with URL parameters

inline

DEMO page http://133.130.101.114//000/en/user/quick_search/index

controller (register sender name and show its value with input field)

  $scope.departChartName = "yoyoyo" urlBinder.bind($scope, "departChartName", "DPNAME") 

slider pointer

 app.directive('ionslider',function($timeout){ return{ restrict:'AE', scope: false, link:function(scope, element, attr, ctrl){ $(element).ionRangeSlider({ chartName: element.attr("chart-name"), onChange: function(slider) { scope[this.chartName] = slider.from+"~"+slider.to scope.$apply(); } }); } } }); 
+5
source share
3 answers

You can create a service for two-way binding to a URL parameter:

 angular.module('app').service('urlBinder', ['$location', function($location) { this.bind = function( scope, // angular scope varName, // string : name of the variable on the scope to bind to urlParamName // string : name of the url parameter to bind to ) { // when scope variable changes, update the URL var unhookUrlUpdater = scope.$watch(varName, function(newValue) { $location.search(urlParamName, newValue); }); // when the URL changes, update the scope variable var unhookScopeUpdater = scope.$on('$locationChangeSuccess', function() { var value = $location.search()[urlParamName]; if (!angular.equals(scope[varName], value)) { scope[varName] = value; } }); // return a function that can be called to remove the bindings return function() { unhookUrlUpdater(); unhookScopeUpdater(); }; }; }]); 

You can also do the same with the getter / setter function instead of varName if the things you are linking are not in scope:

 angular.module('app').service('urlBinder', ['$location', function($location) { this.bind = function(scope, getter, setter, urlParamName) { var unhookUrlUpdater = scope.$watch(getter, function(newValue) { $location.search(urlParamName, newValue); }); var unhookScopeUpdater = scope.$on('$locationChangeSuccess', function() { var value = $location.search()[urlParamName]; if (!angular.equals(getter(), value)) { setter(value); } }); return function() { unhookUrlUpdater(); unhookScopeUpdater(); }; }; }]); 

In your controller:

 var someVariable; urlBinder.bind( $scope, function() { return someVariable; }, function(value) { someVariable = value; }, 'url-name'); 
+3
source

you need to use and with this you load your html ... so now, in your configuration, you can say something like this:

 app.config(['$routeProvider', "$locationProvider", function ($routeProvider, $locationProvider) { /** * Redirect Using Code: * Internal: $location.path([path]); * External: $window.location.href([link]); */ $routeProvider .when("/Taraz/:parent", { templateUrl: "/App/pages/taraz/index.html", controller: "TarazIndexController", resolve: { urlId: ["$route", function ($route) { return Utility.parseUrlId($route.current.params.parent);//Parent HsbCod }] } }) 

here I use / taraz / {code} to access my data. u use // {your data} change the url of the desired ... secondly ... I allow urlId ... it is very similar to the service, you pass it to your controller, but note: if you call one and the other the same page using several routes, you should always allow it (empty or full).

 app.controller('TarazIndexController', ['$rootScope', '$scope', '$location', '$uibModal', 'urlId', 'FinYearService', 'SarfaslService', 'TarazService', function ($rootScope, $scope, $location, $uibModal, urlId, FinYearService, SarfaslService, TarazService) { 

you can use location.path () to send data and change the route. location.path ([route]) ....

.................................................. ..............

there is another way that you can use ui-route, which is more complex and more functional. it's kind of like ng-view, but since I haven't used it myself, I can't help you.

0
source

$ location has getter and setter. If you look at

https://docs.angularjs.org/api/ng/service/ $ location

 url([url]); This method is getter / setter. path([path]); This method is getter / setter. 

You can also use search or replace

 this.$location.search(urlParamName, newValue); replace(); If called, all changes to $location during the current $digest will replace the current history record, instead of adding a new one. 

.when('/about/:name',{})

 app.controller("aboutCtrl",function($scope,$routeParams,$route,$location){ $scope.variable = "'From About Controller'"; $scope.params = $routeParams.name; $scope.locationpath = $location.path(); $scope.absolutelocationurl = $location.absUrl(); $scope.locationurl = $location.url(); $scope.templateurl = $route.current.templateUrl; }); 
0
source

Source: https://habr.com/ru/post/1245842/


All Articles