I’ve had a lot of troubles to display a datetimepicker inside a bootstrap modal window. I’ve tried several ways to display the datetimepicker but none of them worked (delegate, z-index, etc.)

The problem I think, is we tried to initialize the datetimepicker before it gets added to the DOM, because of the animation on the modal window.
I tried also to initialize the datetimepicker on the ‘opened’ event of the modal window like so

<div class="row">
            <div class="'col-sm-3'">
                <div class="form-group">
                    <div class="'input-group" id="'datetimepicker'">

                        <span class="input-group-addon">
                            <span class="glyphicon glyphicon-time"></span>
                        </span>
                    </div>
                </div>
            </div>
        </div>
var modal = $modal.open({
      templateUrl: ...,
      controller: ...
});
modal.result.then(function (result) {
     $state.go('avisos', null, {reload: true});
}, function () {
    $state.go('^');
 });

modal.opened.then(function(){
     console.log('modal opened');
     $('#datetimepicker').datetimepicker({ format: 'DD/MM/YYYY'});
});

the event gets fired before the datetimepicker is in place and therefore not initialized correctly. So, the solution for me was to initialize the datetimepicker in a timeout function inside my angular controller

setTimeout(function () {
     $('#datetimepicker').datetimepicker({
         format: 'DD/MM/YYYY'
     });
}, 1000);
Anuncios

ng-if, ng-hide y ng-show nos sirven para mostrar u ocultar algún elemento de nuestra interfaz, pero lo hacen de forma diferente.

ng-if remueve el elemento del DOM, mientras que ng-hide o ng-show sólo lo ocultan mediante atributos HTML. En AngularJS esta diferencia es importante ya que además de esto, el primero crea un nuevo scope y los otros no. Esto quiere decir que para utilizar las variables de nuestro scope principal tenemos que hacerlo a través del atributo $parent o utilizando un objeto para almacenar nuestras variables, ya que al hacerlo así el mecanismo de js buscaría la propiedad en el scope actual y si no la encuentra la buscaría en el padre.

usando $parent

<input type="text" ng-model="data">
<div ng-if="true">
    <input type="text" ng-model="$parent.data">
</div>

utilizando un objeto

<input type="text" ng-model="data.input">
<div ng-if="true">
    <input type="text" ng-model="data.input">
</div>

Fuentes:
http://stackoverflow.com/questions/19177732/what-is-the-difference-between-ng-if-and-ng-show-ng-hide

En Java y C# es muy común utilizar la sobrecarga de operadores para, por ejemplo, tener un método con el mismo nombre pero distintos parámetros.

    public String sayHi(String name){
        return "hi " + name +"!";
    }

    public String sayHi(String first, String last){
        return sayHi(first + " " + last);
    }

    public String sayHi(String first, String last, String city){
        return sayHi(first, last) + "from " + city;
    }

En javascript no existe la sobrecarga de operadores. Pero podemos hacer algo parecido si pasamos un objeto como parámetro a nuestra función, por ejemplo

$scope.sayHi = function(options){
    var greeting = 'hi '
    if(typeof options.first !== 'undefined' && typeof options.last !== 'undefined' && typeof options.city !== 'undefined'){
        greeting += options.first + ' ' + options.last + ' from ' + options.city
    }else if(typeof options.first !== 'undefined' && typeof options.last !== 'undefined'){
        greeting += options.first + ' ' + options.last
    }
    else if(typeof options.name !== 'undefined'){
        greeting += options.name
    }
    return greeting + '!'
}

Fuentes:
http://stackoverflow.com/questions/456177/function-overloading-in-javascript-best-practices
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters

Fuentes:

http://stackoverflow.com/questions/23455718/why-is-my-ng-model-variable-undefined-in-controller
http://jimhoskins.com/2012/12/14/nested-scopes-in-angularjs.html

A diferencia de AngularJS, ionic utiliza el módulo ui-router en vez de ngRoute para el mecanismo de enrutamiento de las páginas.
En nuestra configuración tendremos estados en vez de rutas. Por ejemplo,

phonecatApp.config(['$routeProvider',
  function($routeProvider) {
    $routeProvider.
      when('/phones', {
        templateUrl: 'partials/phone-list.html',
        controller: 'PhoneListCtrl'
      }).
      when('/phones/:phoneId', {
        templateUrl: 'partials/phone-detail.html',
        controller: 'PhoneDetailCtrl'
      }).
      otherwise({
        redirectTo: '/phones'
      });
  }]);

se convertiría en

    phonecatApp.config(function ($stateProvider, $urlRouterProvider) {
        $stateProvider

            .state('phones', {
                url: '/phones',
                templateUrl: 'partials/phone-list.html',
                controller: 'PhoneListCtrl'
            })

            .state('phones.detail', {
                url: '/:phoneId',
                templateUrl: 'partials/phone-detail.html',
                controller: 'PhoneDetailCtrl'
            })

        $urlRouterProvider.otherwise('/phones')
    })

Y para navegar a otra página, supongamos que tenemos un botón en nuestra plantilla

<button class="button button-block button-positive" ng-click="goTo(phoneId)">
                Detail
</button>

nuestro controlador quedaría

    .controller('PhoneListCtrl', ['$scope', '$state', function($scope, $state){
        $scope.goTo = function(phoneId){
            $state.go('phones.detail', {phoneId: phoneId})
        }
    }])

notesé el paso del parámetro ‘phoneId’

Fuentes:

Para desplegar una lista de opciones agrupadas por un atributo en AngularJS, puedes utilizar el elemento select de la siguiente manera

<select ng-model="myColor" ng-options="color.name group by color.shade for color in colors">
  </select>

Pero ¿qué pasa si tu modelo no contiene un atributo que te permita agrupar los elementos? sino más bien, depende de algún cálculo, varios atributos o cualquier otra condición. Bueno, pues resulta que la cláusula group by es una expresión de AngularJS, esto nos permite utilizar una función para agrupar los elementos. Un ejemplo sería de la siguiente forma.
Supongamos que tenemos el modelo

    $scope.colors = [
      {name:'black', shade:'dark'},
      {name:'white', shade:'light'},
      {name:'red', shade:'dark'},
      {name:'blue', shade:'dark'},
      {name:'yellow', shade:'light'}
    ];

Y queremos crear grupos de acuerdo a la longitud del nombre. Lo haríamos de la siguiente manera

<select ng-model="myColor" ng-options="color.name group by longitud(color) for color in colors"></select>

y en nuestro controlador

        $scope.longitud = function(color){
            var grupo
            switch (color.name.length){
                case 5: grupo = 'Cinco letras'
                    break
                case 4: grupo = 'Cuatro letras'
                    break
                case 3: grupo = 'Tres letras'
                    break
                default: grupo = 'Otro'
            }
            return grupo
        }

De esta forma puedes utilizar cualquier condición para crear los grupos que necesites.

Fuentes:

Desarrollé un servicio web que regresa una respuesta al estilo de SmartGWT

{
"response": {
"status": 0,
"startRow": 0,
"endRow": 76,
"totalRows": 546,
"data": [
{"field1": "value", "field2": "value"},
{"field1": "value", "field2": "value"},
… 76 total records …
]
}
}

Queremos utilizar estos datos en nuestra plantilla

distritos.html

...
<label class="item item-input item-select">
                <div class="input-label">
                    Distrito
                </div>
                <select>
                    <option ng-repeat="distrito in distritos">
                        {{ distrito.descripcion }}
                    </option>
                </select>
            </label>
...

Hay dos formas para poder consumir esta respuesta en nuestra plantilla -a través de un servicio de AngularJS-

Una es utilizar una función transformResponse en la configuración del servicio de la siguiente manera

services.js

'use strict'
angular.module('Equinox.services', ['ngResource'])

    .factory('Distritos', ['$resource', function ($resource) {
        return $resource('http://localhost:8080/equinox/catalogos/distritos', {}, {
            'query': {method: 'GET', isArray: true, transformResponse: function(data){
                return angular.fromJson(data).response.data
            }}
        })
    }])

controllers.js

angular.module('Equinox.controllers', [])

    .controller('DistritosCtrl', ['$scope', 'Distritos', function ($scope, Distritos) {
        $scope.distritos = Distritos.query()

    }])

y la segunda forma es utilizar la respuesta tal y como viene del servidor

services.js

'use strict'
angular.module('Equinox.services', ['ngResource'])

    .factory('Distritos', ['$resource', function ($resource) {
        return $resource('http://localhost:8080/equinox/catalogos/distritos', {}, {
            'query': {method: 'GET', isArray: false}
        })
    }])

controllers.js

angular.module('Equinox.controllers', [])

    .controller('DistritosCtrl', ['$scope', 'Distritos', function ($scope, Distritos) {
        Distritos.query().$promise.then(function(data){
            $scope.distritos = data.response.data
        })
    }])

Fuentes: