AngularJS меняет отображение валюты, манипулируя $locale

Итак, я борюсь с этой проблемой в течение некоторого времени, и все же я не мог найти ответ.

В основном у меня это:

const formattedCurrency = $filter('currency')(input);

Это возвращает мне что-то вроде этого $0.00 ($ кажется угловой валютой по умолчанию CURRENCY_SYM:"$")

Чего я хочу добиться, так это сделать этот возврат не $0.00, а динамической валютой, например €0.00 или £0.00.

Итак, предположим, что у меня есть html-страница с этим текстом:

У меня есть 0,00 долл. США

Если я сделаю это:

this.$locale.NUMBER_FORMATS.CURRENCY_SYM = '€';

Моя страница мгновенно изменится на:

У меня есть 0,00 €

Это здорово, но проблема в том, что я получаю знак валюты из обещания, например:

this.getUserCurrency(this.id).then((currency) => {
    $locale.NUMBER_FORMATS.CURRENCY_SYM = currency; // this does not work
});

И проблема в том, что вышеуказанное не работает, оно не меняет мою HTML-страницу, даже несмотря на то, что мой $locale был изменен.

Мой вывод после моих исследований к настоящему времени таков:

Если я изменю валюту $locale, она автоматически изменит все мои валюты с моей страницы, но если я сделаю это внутри асинхронной функции (promise), моя локаль изменится, но это больше не повлияет на DOM.

Любое решение этой проблемы?


person paulalexandru    schedule 21.11.2017    source источник
comment
Не могли бы вы попробовать функцию (ошибка) { console.error (ошибка) }) в вашей функции обещания   -  person Sourabh    schedule 21.11.2017
comment
1 сек я отвечу. Я отсутствовал, но теперь я проверяю ответы   -  person paulalexandru    schedule 21.11.2017
comment
Есть отзывы м8?   -  person lin    schedule 29.11.2017
comment
Здравствуйте, я отказался от этого, так как не получил разрешения на редактирование дочернего приложения, и поскольку ответ не дал мне решения для изменения только родительского приложения. Я проголосовал за ваш ответ, и, вероятно, многие другие сочтут его полезным и также проголосуют за него. Ваше здоровье   -  person paulalexandru    schedule 30.11.2017


Ответы (2)


$filter в компоненте AngularJS и $locale не являются частью цикла дайджеста. Таким образом, вы не сможете запустить автоматическое $scope обновление, изменив $locale объект конфигурации. На мой взгляд, это лучший способ не использовать $locale как часть цикла дайджеста (потому что вы не можете сделать это таким образом).

Вы должны сохранить конфигурацию своей валюты в глобальной доступной переменной или фабрике (что является частью цикла дайджеста). Вы можете использовать $rootScope, чтобы ваша привязка E2E работала хорошо. Также установите свою валюту в $locale.NUMBER_FORMATS.CURRENCY_SYM, чтобы продолжить эту настройку в других частях кода.

Вид:

<div ng-controller="MyCtrl">
   {{ value | currency: $root.currencySymbol }}
</div> 

Приложение AngularJS:

var myApp = angular.module('myApp',[]);

myApp.controller('MyCtrl', function ($scope, $rootScope, $filter, $locale, $http, $timeout) {

   $scope.value = 0.00;
   $rootScope.currencySymbol = $locale.NUMBER_FORMATS.CURRENCY_SYM;

   $http.get('https://jsonplaceholder.typicode.com/posts').then(function (result) {
      $rootScope.currencySymbol = '€';
      $locale.NUMBER_FORMATS.CURRENCY_SYM = '€';
   });
});

>> Демонстрационная скрипта


Тот же подход с использованием фабрики:

Вид

<div ng-controller="MyCtrl">
   {{ value | currency: $root.currencyHandler.symbol }}
</div>

Приложение AngularJS

var myApp = angular.module('myApp',[]);

myApp.controller('MyCtrl', function (
  $scope, 
  $rootScope, 
  $filter, 
  $locale, 
  $http, 
  $timeout,
  currencyHandler
  ) {

   $scope.value = 0.00;
   $rootScope.currencyHandler = currencyHandler;

   $http.get('https://jsonplaceholder.typicode.com/posts').then(function (result) {
      currencyHandler.setCurrencySymbol('€');
   });
});

myApp.factory('currencyHandler', function ($locale) {
    return {
    symbol: $locale.NUMBER_FORMATS.CURRENCY_SYM,
    setCurrencySymbol: function (value) {
      this.symbol = value;
        $locale.NUMBER_FORMATS.CURRENCY_SYM = value;
    }
  }
});

>> Демонстрационная скрипта


Другой подход с использованием $watch внутри factory:

Таким образом, вы можете установить $locale.NUMBER_FORMATS.CURRENCY_SYM непосредственно в логике вашего контроллера:

Вид

<div ng-controller="MyCtrl">
   {{ value | currency: $root.currencyHandler.symbol }}
</div>

Приложение AngularJS

var myApp = angular.module('myApp',[]);

myApp.controller('MyCtrl', function (
  $scope, 
  $rootScope, 
  $filter, 
  $locale, 
  $http, 
  $timeout,
  currencyHandler
  ) {

   $scope.value = 0.00;
   $rootScope.currencyHandler = currencyHandler;

   $http.get('https://jsonplaceholder.typicode.com/posts').then(function (result) {
      $locale.NUMBER_FORMATS.CURRENCY_SYM = '€'
   });
});

myApp.factory('currencyHandler', function ($locale, $rootScope) {

  let currencyHandler = {
    symbol: $locale.NUMBER_FORMATS.CURRENCY_SYM
  };

  $rootScope.$watch(function () {
    return $locale.NUMBER_FORMATS.CURRENCY_SYM;
  }, function (value) {
    currencyHandler.symbol = value;
  });

  return currencyHandler;
});

>> Демонстрационная скрипта

person lin    schedule 21.11.2017
comment
Дело в том, что мне приходится иметь дело с двумя приложениями, родительским и дочерним приложением. В дочернем приложении у меня есть curency. В родительском приложении у меня есть $locale. Дочернее приложение импортируется в родительское через пакет npm. Я вынужден редактировать только родителя. Поэтому я не могу изменить дочерний элемент, а это означает, что у меня нет доступа к шаблонам для редактирования этого {{ value | валюта: $root.currencyHandler.symbol }}. Вот почему я был вынужден проверить решение через $locale, потому что если я изменю $locale в родительском приложении, дочернее приложение будет работать без каких-либо изменений. - person paulalexandru; 21.11.2017
comment
@paulalexandru Понятно. Sooo, нет решения для этого. Вам нужно вручную выполнять $filter('currency')(input); каждый раз, когда $locale.NUMBER_FORMATS.CURRENCY_SYM изменяется. - person lin; 21.11.2017
comment
Хорошо, мужик, спасибо за помощь. Я оценю ваш ответ и постараюсь выяснить, смогу ли я получить разрешение на внесение изменений в дочернее приложение. - person paulalexandru; 21.11.2017
comment
@paulalexandru Рад помочь тебе. Вы можете принять этот ответ? знак равно - person lin; 21.11.2017
comment
Честно говоря, я думал, что существует существующее решение с $locale. В настоящее время я пытаюсь получить разрешения на изменение дочернего приложения, и если я получу и мне удастся реализовать код, и он работает, я да. - person paulalexandru; 21.11.2017
comment
@paulalexandru хорошо, хорошо. В следующий раз, пожалуйста, предоставьте всю информацию о вашей заявке. Таким образом, мы можем создать для вас полный квалифицированный ответ. Отсутствует информация, например, 2 приложения - невозможность доступа к шаблонам является важным ограничением. - person lin; 21.11.2017
comment
Однако есть кое-что странное. Изменение $locale работает, если оно не находится внутри промиса. - person paulalexandru; 21.11.2017
comment
@paulalexandru нет, это не запускает цикл дайджеста -› jsfiddle.net/occwg3ry это работает только во время настройки до того, как начнется первый цикл дайджеста. непосредственно в вашем контроллере. -› jsfiddle.net/386weuLb Но это влияет только на каждую $locale зависимость, которая используется после этого установщика символа валюты. Он по-прежнему не запускает цикл дайджеста. знак равно - person lin; 21.11.2017
comment
Так нет ли способа динамически изменить $locale? Что-то нашел здесь lgalfaso.github.io/angular-dynamic-locale - person paulalexandru; 21.11.2017
comment
@paulalexandru это вам не поможет, потому что он использует цикл дайджеста, как решение, которое я предоставил с помощью {{1000000 | currency}}. Ваш код $filter('currency')(input); не является частью цикла дайджеста. Так что это не будет работать для вас. - person lin; 21.11.2017

Вы можете заставить angularjs обновить влияние $locale через $state.reload().

person Dev93    schedule 09.05.2019