离子 - 交换列表中的交换元素

时间:2016-08-17 17:39:08

标签: javascript angularjs ionic-framework

我有一个离子列表,显示使用ng-repeat的用户列表。 我试图做的是在收到通知时将其中一个用户从他的位置移动到顶部,有点像在whatsapp聊天中收到消息时。传递给列表的数组在控制器中定义,如下面的代码所示。

listUsers.html:

<ion-view title="listaUsers" can-swipe-back="true">
    <ion-content overflow-scroll="true" padding="false" scroll="true" class="has-header">
        <ion-list ng-repeat="session in listUsers">
            <a class="item item-avatar" href="#/app/profile/listUsers/chat/{{session.id}}">

                <img ng-src="http://sviluppo.asuscomm.com:43280/mob/ionic/immagini_{{session.social}}/{{session.id}}.jpg" err-SRC="img/default-user.png" />

                <h2>{{session.nome}} - {{session.cognome}}</h2>
                <p>{{session.messaggio}}</p>


                <div ng-if="session.in_out_struttura == 1">
                    <span class="badge badge-balanced">SI</span>

                </div>
                <div ng-if="session.in_out_struttura == 0">
                    <span class="badge badge-assertive">NO</span>
                </div>

            </a>
        </ion-list>
    </ion-content>
</ion-view>

listUsers.js:

angular.module('app.controllers')

.controller('listUsersCtrl', function ($scope, $http, $rootScope, $ionicLoading) {

    $scope.listUsers = []; 
    /*Some function will put the data into $scope.listUsers, 
      every element will be a JSON object like this:
        {
            id: 1,
            nome: "John",
            cognome: "Doe",
            social: "F",
            messaggio: "Some Message"
        }
    */

    //This function removes the record to move from the array and puts it back into it in first position
    $scope.putOnTop = function (id_usr, message) {
        for (var x = 0; x < $scope.listUsers.length; x++) {
            if ($scope.listUsers[x].id == id_usr) {
                var record = $scope.listUsers.splice(x, 1)[0];
                record.messaggio = message;
                $scope.listUsers.unshift(record); 
                break;
            }
        }
    }

    //This listens to a custom event emitted from app.js
    $rootScope.$on("putUserOnTop", function (event, id_usr, message) {
        $scope.putOnTop(id_usr, message);
    });


})

app.js:

//This is just a part of the original app.js
angular.module('app', ['ionic', 'app.controllers', 'app.routes', 'app.services', 'app.directives', 'pascalprecht.translate', 'ngCordova', 'ngCordovaOauth', 'ionic-datepicker'])

.run(function ($ionicPlatform, $translate, $http, $state, $ionicHistory, $rootScope, $cordovaNetwork) {

    //...

    $ionicPlatform.ready(function () {

        //...

        try {
            var push = PushNotification.init({
                android: {
                    senderID: "XXXXXXXXXX"
                },
                ios: {
                    alert: "true",
                    badge: "true",
                    sound: "true"
                },
                windows: {}
            });
        } catch (e) {
            console.log("ERROR PUSH NOTIFICATION : " + e);
        }

        try {
            push.on('registration', function (data) {
                localStorage.setItem("registrationId", data.registrationId);
            });


            push.on('notification', function (data) {

                var senderId = data.additionalData.senderId;
                var destId = data.additionalData.destId;
                var message = data.additionalData.messaggio;

                //Checking if the app was in foreground, background or not running
                if (data.additionalData.coldstart !== undefined) {
                //THE WAS NOT IN FOREGROUND
                    if ($ionicHistory.currentView().url == "/app/profile/listUsers") {
                        $rootScope.$emit("putUserOnTop", senderId, message);
                    } else if ($ionicHistory.currentView().url == "/app/profile/listUsers/chat/" + senderId) {
                        //...
                    } else {
                        //...
                    }
                } else {
                    //THE APP WAS IN FOREGROUND
                    $rootScope.$emit("putUserOnTop", senderId, message);
                    //...
                }

            });

            push.on('error', function (e) {
                //...
            });
        } catch (e) {
            console.log("ERROR : " + e);
        }

        //...

})

.config(...);

问题是,如果我运行此代码,则记录不会在列表中移动,并且控制台中不会显示错误。如果我使用按钮运行putOnTop函数,它实际上工作正常。我错过了什么?

感谢。

修改

我还尝试使用$cordovaPushV5代替PushNotification,相应地修改代码,但没有任何改变,相同的行为。以下是更新的 app.js

//This is just a part of the original app.js
angular.module('app', ['ionic', 'app.controllers', 'app.routes', 'app.services', 'app.directives', 'pascalprecht.translate', 'ngCordova', 'ngCordovaOauth', 'ionic-datepicker'])

.run(function ($ionicPlatform, $translate, $http, $state, $ionicHistory, $rootScope, $cordovaNetwork, $cordovaPushV5) {

    //...

    $ionicPlatform.ready(function () {

        //...

        $cordovaPushV5.initialize({
            android: {
                senderID: "XXXXXXXXXX"
            },
            ios: {
                alert: "true",
                badge: "true",
                sound: "true"
            },
            windows: {}
    }).then(function() {
        // start listening for new notifications
        $cordovaPushV5.onNotification();
        // start listening for errors
        $cordovaPushV5.onError();

        // register to get registrationId
        $cordovaPushV5.register().then(function(registrationId) {
            localStorage.setItem("registrationId", registrationId);
        });
    });

    $rootScope.$on('$cordovaPushV5:notificationReceived', function(event, data){
        var senderId = data.additionalData.senderId;
        var destId = data.additionalData.destId;
        var message = data.message;
        var timestamp = data.additionalData.timestamp;

        if (data.additionalData.coldstart !== undefined) {
            if ($ionicHistory.currentView().url == "/app/profile/listUsers") {
                $rootScope.$emit("putUserOnTop", [senderId, message, timestamp]);
            } else if ($ionicHistory.currentView().url == "/app/profile/listUsers/chat/" + senderId) {
                $rootScope.$emit("getMessages", {
                    senderId: senderId,
                    destId: destId
                });
            } else {
                $state.go("app.chat", {
                    userId: senderId
                });
            }
        } else {
            if ($ionicHistory.currentView().url == "/app/profile/listUsers") {
                $rootScope.$emit("putUserOnTop", [senderId, message, timestamp]);
            } else if ($ionicHistory.currentView().url == "/app/profile/listUsers/chat/" + senderId) {
                $rootScope.$emit("getMessages", {
                    senderId: senderId,
                    destId: destId
                });
            }

        }
    });

    // triggered every time error occurs
    $rootScope.$on('$cordovaPushV5:errorOcurred', function(event, e){
        //...
    });

    //...

})

.config(...);

3 个答案:

答案 0 :(得分:0)

问题在于你从$rootScope.$on得到论据的方式。参数将在第二个参数中,如下所示:

$rootScope.$on("putUserOnTop", function (event, args) {
    var id_usr = args.id_usr;
    var message = args.message;
    $scope.putOnTop(id_usr, message);
});

答案 1 :(得分:0)

更简单的方法是使用角度滤镜:orderBy。您可以在项目上设置更新的日期属性,然后在desc模式下进行过滤。 e.g:

设置过滤器

let request = CNContactFetchRequest(keysToFetch: [
    CNContactGivenNameKey as CNKeyDescriptor,
    CNContactFamilyNameKey as CNKeyDescriptor,
    CNContactMiddleNameKey as CNKeyDescriptor,
    CNContactEmailAddressesKey as CNKeyDescriptor,
    CNContactPhoneNumbersKey as CNKeyDescriptor
])

do {
    try contactStore.enumerateContacts(with: request) { contact, stop in
        for phone in contact.phoneNumbers {
            // look at `phone.value.stringValue`, e.g.

            let phoneNumberDigits = String(phone.value.stringValue.characters.filter { String($0).rangeOfCharacter(from: CharacterSet.decimalDigits) != nil })

            if phoneNumberDigits == "8885551212" {
                self.results.append(contact)
                return
            }
        }
    }
} catch let enumerateError {
    print(enumerateError.localizedDescription)
}

设置updated_at

<ion-list ng-repeat="session in listUsers | orderBy: '-updated_at'">

$rootScope.$on("putUserOnTop", function (event, id_usr, message) { var user = $scope.listUsers.find(function() { return user.id == id_usr; }); user.updated_at = new Date(); }); 过滤器将使用orderBy属性重新排序您的商品,因此每次收到邮件时,您都可以设置此时间戳以更新收藏顺序。

答案 2 :(得分:0)

好的,只是报告我需要让它工作的所有内容就是$scope.$apply();putOnTop放在$scope.putOnTop = function (id_usr, message) { for (var x = 0; x < $scope.listUsers.length; x++) { if ($scope.listUsers[x].id == id_usr) { var record = $scope.listUsers.splice(x, 1)[0]; record.messaggio = message; $scope.listUsers.unshift(record); $scope.$apply() //<============================ break; } } } 函数中,如下所示:

     1.          for (int i = 0; i < n; i = i + C) 
     2.               for (int j = 0; j < 10; j++)
     3.                  Sum[i] += j * Sum[i]; 

`

 Line 1: int i=0, takes constant time of 1 so O(1)
         i<n, takes n+1 time so O(n)
         i=i+C, takes n time so O(n)



         Total time: 1+(n+1)+n= 2n+2


 Line 2:
         int j=0, takes constant time of 1 so O(1)
         j<10, loops through 10 times and takes n time so O(n)
         i=i+C, loops through 10 times and takes n time so O(n)



         Total time: 1+(10+10)n= 1+20n

 Line 3:


         Sum[i]=Sum[i]+j*Sum[i];

        Addition and Multiplication takes constant time of 2 and plus 1 to store 
        or assign the value, and it loops through n times.


             Total time:3n

T(n)=(2n+2)+(1+20n)+3n= 25n+3 is O(n) right?

感谢大家的帮助!