crear - directivas personalizadas angularjs
Alcance de acceso AngularJS desde fuera de la funciĆ³n js (11)
Aquí hay una solución reutilizable: http://jsfiddle.net/flobar/r28b0gmq/
function accessScope(node, func) {
var scope = angular.element(document.querySelector(node)).scope();
scope.$apply(func);
}
window.onload = function () {
accessScope(''#outer'', function (scope) {
// change any property inside the scope
scope.name = ''John'';
scope.sname = ''Doe'';
scope.msg = ''Superhero'';
});
};
Estoy tratando de ver si hay una manera simple de acceder al alcance interno de un controlador a través de una función javascript externa (completamente irrelevante para el controlador de destino)
He visto en un par de otras preguntas aquí que
angular.element("#scope").scope();
recuperaría el alcance de un elemento DOM, pero mis intentos actualmente no arrojan resultados adecuados.
Aquí está el jsfiddle: http://jsfiddle.net/sXkjc/5/
Actualmente estoy pasando por una transición de simple JS a angular. La razón principal por la que trato de lograr esto es mantener intacto el código de la biblioteca original tanto como sea posible; guardando la necesidad de que agregue cada función al controlador.
¿Alguna idea sobre cómo podría lograr esto? Comentarios sobre el violín anterior también son bienvenidos.
Ha pasado mucho tiempo desde que hice esta pregunta, pero aquí hay una respuesta que no requiere jquery:
function change() {
var scope = angular.element(document.querySelector(''#outside'')).scope();
scope.$apply(function(){
scope.msg = ''Superhero'';
})
}
Ha pasado un tiempo desde que publiqué esta pregunta, pero teniendo en cuenta las opiniones que parece obtener, esta es otra solución que he encontrado durante estos últimos meses:
$scope.safeApply = function( fn ) {
var phase = this.$root.$$phase;
if(phase == ''$apply'' || phase == ''$digest'') {
if(fn) {
fn();
}
} else {
this.$apply(fn);
}
};
El código anterior básicamente crea una función llamada safeApply
que llama a la función $apply
(como se indica en la respuesta de Arun) si Angular actualmente no está pasando por la etapa $digest
. Por otro lado, si Angular está actualmente digiriendo cosas, solo ejecutará la función tal como está, ya que eso será suficiente para indicarle a Angular que haga los cambios.
Se producen numerosos errores cuando se intenta utilizar la función $apply
mientras AngularJs se encuentra actualmente en su etapa de $digest
. El código de safeApply
anterior es un contenedor seguro para evitar dichos errores.
(nota: personalmente me gusta safeApply
en safeApply
como una función de $rootScope
para fines de conveniencia)
Ejemplo:
function change() {
alert("a");
var scope = angular.element($("#outer")).scope();
scope.safeApply(function(){
scope.msg = ''Superhero'';
})
}
Demostración: http://jsfiddle.net/sXkjc/227/
La respuesta aceptada es genial. Quería ver qué sucede con el alcance angular en el contexto de ng-repeat
. El caso es que Angular creará un sub-ámbito para cada artículo repetido. Al llamar a un método definido en el $scope
original, que conserva su valor original (debido al cierre de javascript). Sin embargo, this
hace referencia al alcance / objeto de la llamada. Esto funciona bien, siempre que tenga claro cuándo $scope
y this
es lo mismo y cuando son diferentes. hth
Aquí hay un violín que ilustra la diferencia: https://jsfiddle.net/creitzel/oxsxjcyc/
Necesita usar $scope.$apply() si desea realizar cambios en un valor de ámbito fuera del control de angularjs, como un controlador de eventos jquery / javascript.
function change() {
alert("a");
var scope = angular.element($("#outer")).scope();
scope.$apply(function(){
scope.msg = ''Superhero'';
})
}
Demostración: Fiddle
Necesitamos utilizar Angular Js incorporado en la función $ apply para aceptar las variables de alcance o funciones fuera de la función del controlador.
Esto se puede hacer de dos formas :
| * | Método 1: usar Id:
<div id="nameNgsDivUid" ng-app="">
<a onclick="actNgsFnc()"> Activate Angular Scope</a><br><br>
{{ nameNgsVar }}
</div>
<script type="text/javascript">
var nameNgsDivVar = document.getElementById(''nameNgsDivUid'')
function actNgsFnc()
{
var scopeNgsVar = angular.element(nameNgsDivVar).scope();
scopeNgsVar.$apply(function()
{
scopeNgsVar.nameNgsVar = "Tst Txt";
})
}
</script>
| * | Método 2: usar init de ng-controller:
<div ng-app="nameNgsApp" ng-controller="nameNgsCtl">
<a onclick="actNgsFnc()"> Activate Angular Scope</a><br><br>
{{ nameNgsVar }}
</div>
<script type="text/javascript">
var scopeNgsVar;
var nameNgsAppVar=angular.module("nameNgsApp",[])
nameNgsAppVar.controller("nameNgsCtl",function($scope)
{
scopeNgsVar=$scope;
})
function actNgsFnc()
{
scopeNgsVar.$apply(function()
{
scopeNgsVar.nameNgsVar = "Tst Txt";
})
}
</script>
Soy novato, lo siento si es una mala práctica. Basado en la respuesta elegida, hice esta función:
function x_apply(selector, variable, value) {
var scope = angular.element( $(selector) ).scope();
scope.$apply(function(){
scope[variable] = value;
});
}
Lo estoy usando de esta manera:
x_apply(''#fileuploader'', ''thereisfiles'', true);
Por cierto, perdón por mi inglés
También puedes probar:
function change() {
var scope = angular.element( document.getElementById(''outer'') ).scope();
scope.$apply(function(){
scope.msg = ''Superhero'';
})
}
podemos llamarlo después de cargado
http://jsfiddle.net/gentletech/s3qtv/3/
<div id="wrap" ng-controller="Ctrl">
{{message}}<br>
{{info}}
</div>
<a onClick="hi()">click me </a>
function Ctrl($scope) {
$scope.message = "hi robi";
$scope.updateMessage = function(_s){
$scope.message = _s;
};
}
function hi(){
var scope = angular.element(document.getElementById("wrap")).scope();
scope.$apply(function() {
scope.info = "nami";
scope.updateMessage("i am new fans like nami");
});
}
Otra forma de hacerlo es:
var extScope;
var app = angular.module(''myApp'', []);
app.controller(''myController'',function($scope, $http){
extScope = $scope;
})
//below you do what you want to do with $scope as extScope
extScope.$apply(function(){
extScope.test = ''Hello world'';
})
<input type="text" class="form-control timepicker2" ng-model=''programRow.StationAuxiliaryTime.ST88'' />
acceder al valor del alcance
supongamos que programRow.StationAuxiliaryTime es una matriz de objetos
$(''.timepicker2'').on(''click'', function ()
{
var currentElement = $(this);
var scopeValues = angular.element(currentElement).scope();
var model = currentElement.attr(''ng-model'');
var stationNumber = model.split(''.'')[2];
var val = '''';
if (model.indexOf("StationWaterTime") > 0) {
val = scopeValues.programRow.StationWaterTime[stationNumber];
}
else {
val = scopeValues.programRow.StationAuxiliaryTime[stationNumber];
}
currentElement.timepicker(''setTime'', val);
});