ডিফল্ট মান থেকে কৌণিক js init এনজি-মডেল


126

বলুন আপনার কাছে এমন একটি ফর্ম রয়েছে যা ডাটাবেস থেকে মানগুলি লোড করেছে। আপনি এনজি-মডেলটি কীভাবে শুরু করবেন?

উদাহরণ:

<input name="card[description]" ng-model="card.description" value="Visa-4242">

আমার নিয়ামকটিতে, $ স্কোপকার্ড প্রাথমিকভাবে অপরিবর্তিত। এরকম কিছু করার পাশাপাশি কি উপায় আছে?

$scope.card = {
  description: $('myinput').val()
}

উত্তর:


136

এটি নতুন কৌণিক অ্যাপ্লিকেশনগুলিতে একটি সাধারণ ভুল। আপনি যদি এটিকে এড়াতে পারেন তবে সার্ভারে আপনার মানগুলি আপনার HTML এ লিখতে চান না। যদি সত্য হয়, আপনি যদি নিজের সার্ভারকে পুরোপুরি এইচটিএমএল রেন্ডার করা থেকে দূরে রাখতে পারেন তবে আরও ভাল।

আদর্শভাবে, আপনি আপনার কৌণিক এইচটিএমএল টেমপ্লেটগুলি প্রেরণ করতে চান, তারপরে আপনার মানগুলি JSON এ $ HTTP- র মাধ্যমে নীচে টানুন এবং সেগুলি আপনার আওতায় রাখুন।

তাই যদি সম্ভব হয় তবে এটি করুন:

app.controller('MyController', function($scope, $http) {
    $http.get('/getCardInfo.php', function(data) {
       $scope.card = data;
    });
});

<input type="text" ng-model="card.description" />

আপনি যদি নিজের সার্ভার থেকে আপনার মানটি আপনার এইচটিএমএলকে একেবারে রেন্ডার করতে পারেন তবে আপনি সেগুলি একটি বৈশ্বিক পরিবর্তনশীলতে রেখে them উইন্ডো দিয়ে তাদের অ্যাক্সেস করতে পারেন:

আপনার পৃষ্ঠার শিরোনামে আপনি লিখতে চান:

<head>
   <script>
       window.card = { description: 'foo' };
   </script>
</head>

এবং তারপরে আপনার নিয়ামকটিতে আপনি এটি এর মতো পাবেন:

app.controller('MyController', function($scope, $window) {
   $scope.card = $window.card;
});

আমি আশা করি এটি সাহায্য করবে.


4
হ্যাঁ, এটি সাহায্য করে। আমার ধারণা আমি কৌতুকপূর্ণ ছেলেরা এই সিদ্ধান্ত নিয়েছে যে আমি কেবল হতবাক হয়েছি।
ক্যালভিন ফ্রয়েজ

125
হতবাক হবেন না ... এইচটিএমএল রেন্ডারিং সার্ভার এবং ব্রাউজারে সরে যাচ্ছে। আজকাল জাভাস্ক্রিপ্টে কয়েক ডজন এমভিসি ফ্রেমওয়ার্ক রয়েছে এবং এটি কোনও সার্ভারের পক্ষে জাভাস্ক্রিপ্ট অ্যাপ্লিকেশনগুলিতে জেএসএন / এক্সএমএল ডেটা হোস্ট করা যতটা সার্ভারের প্রতিটি পৃষ্ঠাকে রেন্ডার করার চেয়ে বেশি কার্যকর। এটি সার্ভার হিট না করে ক্লায়েন্টের মেশিনে প্রচুর কাজ অফসেট করে। এটি ব্যান্ডউইথ উপর সংরক্ষণ করে উল্লেখ করা না। এগুলি সর্বোপরি, আপনার একটি নেটিভ মোবাইল অ্যাপ (বা সত্যিই কিছু) থাকতে পারে যা HTTP- র মাধ্যমে একই JSON গ্রাস করে। এটাই ভবিষ্যত।
বেন লেশ

3
@blesh: দুর্দান্ত উত্তর। অনেক ধন্যবাদ. আমি সম্মত হই যে এটিই এগিয়ে যাওয়ার পথ এবং এই পদ্ধতিটি নিজেই গ্রহণ করা শুরু করেছি; আপনার কি এমন কোনও লিঙ্ক রয়েছে যা এই দাবিকে সমর্থন করে? আমি আরও শঙ্কিত যে সার্ভার থেকে এইচটিএমএল রেকর্ডিংটি ক্লায়েন্টে স্থানান্তরিত করার ফলে ধীরে ধীরে পৃষ্ঠা লোডের সময় হতে পারে, বিশেষত এমন মোবাইল ডিভাইসগুলিতে যেখানে আপনি নেভিগেশন গাছের জন্য অনেকগুলি HTML উপস্থাপন করতে পারেন।
GFoley83

19
আমি একমত না যে এটি একটি 'ভুল'। কিছু ক্ষেত্রে ক্লায়েন্ট-সাইড রেন্ডারিং সেরা সমাধান। অন্যদের মধ্যে, সার্ভার-সাইড রেন্ডারিংয়ের উপায়। আপনি উভয় কৌশল দিয়ে কৌণিক ব্যবহার করতে পারেন এবং ক্লায়েন্ট-সাইড রেন্ডারিংটি "কৌণিক উপায়" হিসাবে ধরে রাখা উচিত নয় কারণ এটি তা নয়। কৌণিক তার চেয়ে আরও নমনীয়।
হান্টারলফটিস

8
@blesh, অবশ্যই - এসইও গুরুত্বপূর্ণ যেখানে যে কোনও উদাহরণ কিন্তু ক্রলারগুলির জন্য বিকল্প সামগ্রীর ব্যয় এম্বেডড ডেটা সহ কৌণিক প্রয়োগের ব্যয়ের চেয়ে বেশি - এমন কোনও অ্যাপ্লিকেশন যা অনুমিত গতি বা সময়-প্রতি-রেন্ডারে খুব উচ্চ মূল্য দেয় p ব্যবহারকারীর অভিজ্ঞতা - অনেকগুলি কন্টেন্ট সাইট এবং ইকমার্স সাইটগুলি এই বিভাগগুলির মধ্যে একটির মধ্যে পড়ে। টুইটারে ইঞ্জিনিয়াররা, যারা ক্লায়েন্টের রেন্ডারিংয়ের চেষ্টা করেছিলেন তারপরে আরও ভাল ব্যবহারকারীর অভিজ্ঞতা সরবরাহ করার জন্য সার্ভারে ফিরে গিয়েছিলেন, তাদের যুক্তিটিও এর রূপরেখা দিয়েছেন: ব্লগ.টুইটার.কম
2012

236

আপনি যদি আপনার অ্যাপ্লিকেশনটিকে পুনরায় কাজ করতে না পারেন তবে @blesh এর পরামর্শ অনুসারে (JSON ডেটাটি নীচে $ HTTP বা $ সংস্থান এবং পপুলেট করুন $ স্কোপ দিয়ে টানুন), আপনি এর পরিবর্তে এনজি-থিং ব্যবহার করতে পারেন :

<input name="card[description]" ng-model="card.description" ng-init="card.description='Visa-4242'">

অ্যাংুলারজেএসও দেখুন - কোনও এনজি-মডেল ব্যবহার করার সময় কোনও ইনপুট পাঠ্য বাক্সে মান বৈশিষ্ট্যটি উপেক্ষা করা হয়?


কৌণিক উপায়ে (কম পছন্দের অনুশীলনের জন্য) +1। উদাহরণ: jsfiddle.net/9ymB3
জন লেহম্যান

2
আমি সি # ওয়েব ফর্মের সাথে কৌণিক ব্যবহার করছি এবং আমি দেখতে ng-initপেয়েছি কোড-পিছন / পোস্টব্যাক থেকে মান নির্ধারণের সময় ব্যবহার করা বেশ কার্যকর <input name="phone" data-ng-model="frm.phone" data-ng-init="frm.phone= '<%: Model.Phone %>'" data-ng-pattern="/^[0-9() \-+]+$/" type="tel" required />। বিট কুৎসিত? হ্যাঁ, তবে কৌতুকটি ও প্রক্রিয়াটিতে একটি সংহত মাথাব্যাথা সমাধান করে।
জিএফোলি 83

13
+1, মার্জিত! লোকেরা চটজলদি এবং তাত্পর্যপূর্ণ আচরণের পক্ষে, তবে এখানে এসও তে অনেকেই বলেছেন "এটি সমস্ত ক্লায়েন্টের পক্ষেই করুন।", লক্ষ লক্ষ পোস্টের মত স্মার্ট সাইটগুলির জন্য ভাল। টেমপ্লেটগুলিতে ডেটা সার্ভারের সাইডটি সিডিং কৌশলগুলি সক্ষম করে। স্থির, বা মেমচেডযুক্ত গতিশীল / আংশিক। টুইটার এটিই করে। কখনও কখনও এটি দরকারী, অন্য সময় না। যে চাপ দিতে চেয়েছিলেন। কেবল এটি যোগ করতে হয়েছিল, আপনি অন্যথায় বলেছেন না যে, @ মার্ক
oma

1
প্রকৃতপক্ষে আমি এটি ফিরিয়ে নিই, এটি আমার পক্ষে সবচেয়ে দুর্দান্ত কাজ করে, দুর্দান্ত: stackoverflow.com/a/20522955/329367
ড্যারেন

1
এফডাব্লুআইডাব্লু: টেমপ্লেট এক্সপ্রেশনগুলিতে ভেরিয়েবল অ্যাসাইনমেন্টটি আমি পছন্দ করি না কারণ এটি পরীক্ষাযোগ্য নয়।
বেন লেশ

60

এটি স্পষ্টতই অভাব, তবে অ্যাঙ্গুলারজেএস-এর জন্য সহজেই যুক্ত করা ফিক্স। ইনপুট ক্ষেত্র থেকে মডেল মান সেট করতে কেবল একটি দ্রুত নির্দেশ লিখুন write

<input name="card[description]" value="Visa-4242" ng-model="card.description" ng-initial>

আমার সংস্করণটি এখানে:

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

app.directive('ngInitial', function() {
  return {
    restrict: 'A',
    controller: [
      '$scope', '$element', '$attrs', '$parse', function($scope, $element, $attrs, $parse) {
        var getter, setter, val;
        val = $attrs.ngInitial || $attrs.value;
        getter = $parse($attrs.ngModel);
        setter = getter.assign;
        setter($scope, val);
      }
    ]
  };
});

দুর্দান্ত দ্রুত নির্দেশ। এটিকে এনজি-মডেলে প্যাকেজ না করার কোনও ভাল কারণ যাতে মান = এবং এনজি-মডেল = বেশিরভাগ লোকেরা প্রত্যাশা মতো একসাথে কাজ করতে পারে?
হান্টারলফটিস

বেশ সুন্দর! এটি দরকারী।
সান্তিয়াগোবসুল্টো

3

আপনি কেন controllerআপনার নির্দেশনার জন্য সংজ্ঞা দিয়েছেন এবং কেন linkপদ্ধতিটি ব্যবহার করেননি ? আমি অ্যাঙ্গুলার্সে নবাগত
ইব্রাম খলিল

1
val = $attrs.ngInitial || $attrs.value || $element.val()এটি নির্বাচনের উপাদানগুলির সাথে কাজ করার জন্য পরিবর্তিত হওয়া দরকার ।
fjsj

12

আইএমএইচও এর সেরা সমাধানটি হ'ল কেভিন স্টোন নির্দেশিকা, তবে আমাকে প্রতিটি অবস্থাতেই কাজ করার জন্য এটি আপগ্রেড করতে হয়েছিল (ফে সিলেক্ট, টেক্সারিয়া), এবং এইটি নিশ্চিতভাবে কাজ করছে:

    angular.module('app').directive('ngInitial', function($parse) {
        return {
            restrict: "A",
            compile: function($element, $attrs) {
                var initialValue = $attrs.value || $element.val();
                return {
                    pre: function($scope, $element, $attrs) {
                        $parse($attrs.ngModel).assign($scope, initialValue);
                    }
                }
            }
        }
    });

এবং নির্বাচন সম্পর্কে কি?
jwize

7

আপনি একটি কাস্টম নির্দেশিকা ব্যবহার করতে পারেন (টেক্সারিয়া, নির্বাচন, রেডিও এবং চেকবক্সের সমর্থন সহ), এই ব্লগ পোস্টটি https://glaucocustodio.github.io/2014/10/20/init-ng-model-from-form- দেখুন ক্ষেত্র-বৈশিষ্ট্য /


1
এটি একটি মহান পোস্ট। প্রশ্নটির পরে আমার প্রিয় উত্তরটি ছিল আদ্যক্ষরগুলির মান অনুসারে একটি ইনপুটটির মান সেট করা।
আরপিডিজেসিস 13

আমি এই কোডটি পরীক্ষা করার জন্য একটি Plnkr তৈরি করেছি এবং এটি দুর্দান্ত কাজ করে: plnkr.co/edit/ZTFOAc2ZGIZr6HjsB5gH?p= পূর্বরূপ
আরপিডিশাইজ

6

আপনি আপনার HTML কোডের মধ্যেও ব্যবহার করতে পারেন: ng-init="card.description = 12345"

এটি কৌণিক দ্বারা প্রস্তাবিত নয়, এবং উপরে বর্ণিত হিসাবে আপনার একচেটিয়াভাবে আপনার নিয়ামক ব্যবহার করা উচিত।

কিন্তু এটি কাজ করে :)


4

আমার একটি সহজ পদ্ধতি রয়েছে, কারণ আমার ফর্মগুলিতে আমার কিছু ভারী বৈধতা এবং মুখোশ রয়েছে। সুতরাং, আমি আবার আমার মূল্য পেতে jquery ব্যবহার করেছি এবং ইভেন্টটিকে "পরিবর্তন" বৈধতাগুলিতে ফেলা:

$('#myidelement').val('123');
$('#myidelement').trigger( "change");

3

অন্যরা যেমন উল্লেখ করেছে, ভিউগুলিতে ডেটা শুরু করা ভাল অনুশীলন নয়। কন্ট্রোলারগুলিতে ডেটা শুরু করার পরামর্শ দেওয়া হয়। (দেখুন http://docs.angularjs.org/guide/controller )

সুতরাং আপনি লিখতে পারেন

<input name="card[description]" ng-model="card.description">

এবং

$scope.card = { description: 'Visa-4242' };

$http.get('/getCardInfo.php', function(data) {
   $scope.card = data;
});

এইভাবে দর্শনগুলিতে ডেটা থাকে না এবং কন্ট্রোলার আসল মান লোড হওয়ার সময় মানটি আরম্ভ করে।


3

আপনি যদি উপরের কেভিন স্টোনর পদ্ধতির পছন্দ করেন তবে https://stackoverflow.com/a/17823590/584761 নির্দিষ্ট ট্যাগ যেমন 'ইনপুট' এর জন্য নির্দেশিকা লিখে একটি সহজ পদ্ধতির বিবেচনা করুন।

app.directive('input', function ($parse) {
    return {
        restrict: 'E',
        require: '?ngModel',
        link: function (scope, element, attrs) {
            if (attrs.ngModel) {
                val = attrs.value || element.text();
                $parse(attrs.ngModel).assign(scope, val);
            }
        }
    }; });

আপনি যদি এই পথে যান তবে আপনাকে প্রতিটি ট্যাগে এনজি-ইনিশিয়াল যোগ করার বিষয়ে চিন্তা করতে হবে না। এটি স্বয়ংক্রিয়ভাবে ট্যাগটির মান বৈশিষ্ট্যটিতে মডেলের মান সেট করে। আপনি যদি মানটির বৈশিষ্ট্যটি সেট না করেন তবে এটি একটি খালি স্ট্রিংয়ে ডিফল্ট হবে।


3

এখানে একটি সার্ভার কেন্দ্রিক পদ্ধতির:

<html ng-app="project">
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
    <script>
        // Create your module
        var dependencies = [];
        var app = angular.module('project', dependencies);

        // Create a 'defaults' service
        app.value("defaults", /* your server-side JSON here */);

        // Create a controller that uses the service
        app.controller('PageController', function(defaults, $scope) {
            // Populate your model with the service
            $scope.card = defaults;
        });
    </script>

    <body>
        <div ng-controller="PageController">
            <!-- Bind with the standard ng-model approach -->
            <input type="text" ng-model="card.description">
        </div>
    </body>
</html>

এই প্রশ্নের আরও জনপ্রিয় উত্তরগুলির মতো একই বুনিয়াদী ধারণা ,। সরবরাহ.মূল্যটি এমন কোনও পরিষেবা নিবন্ধন করে যা আপনার ডিফল্ট মানগুলি অন্তর্ভুক্ত করে।

সুতরাং, সার্ভারে, আপনার মতো কিছু থাকতে পারে:

{
    description: "Visa-4242"
}

এবং এটি আপনার পছন্দের সার্ভার-সাইড প্রযুক্তির মাধ্যমে আপনার পৃষ্ঠাতে রেখে দিন। এখানে একটি সংক্ষিপ্ত বিবরণ: https://gist.github.com/exclsr/c8c391d16319b2d31a43


1
যতদূর আমি বলতে পারি, প্রাথমিক $ HTTP অনুরোধ করা কোনও বিকল্প না হলে সমস্যাটি পরিচালনা করার পক্ষে এটি সবচেয়ে কৌণিক পদ্ধতি। আপনি পরে $ http এ অদলবদল করতে চাইলে এটি পরিবর্তন করতে আরও সহজ হওয়ার সুবিধা রয়েছে। একটি সম্ভাব্য বর্ধন হ'ল পরিবর্তনের ব্যবস্থাটিকে আরও সহজ করার পরিবর্তে কোনও প্রতিশ্রুতি ফেরানো। আমি এখানে গ্লোবাল ভার্সেস সেট করা বা এনজি-প্রাথমিক ব্যবহার করা থেকে খুব লজ্জা পাব।
রিচার্ড

1

এইটি উপরে বর্ণিত ধারণাগুলির আরও জেনেরিক সংস্করণ ... এটি কেবলমাত্র মডেলের কোনও মান আছে কিনা তা যাচাই করে এবং যদি তা না হয় তবে এটি মডেলের মান নির্ধারণ করে।

জাতীয়:

function defaultValueDirective() {
    return {
        restrict: 'A',
        controller: [
            '$scope', '$attrs', '$parse',
            function ($scope, $attrs, $parse) {
                var getter = $parse($attrs.ngModel);
                var setter = getter.assign;
                var value = getter();
                if (value === undefined || value === null) {
                    var defaultValueGetter = $parse($attrs.defaultValue);
                    setter($scope, defaultValueGetter());
                }
            }
        ]
    }
}

এইচটিএমএল (ব্যবহারের উদাহরণ):

<select class="form-control"
        ng-options="v for (i, v) in compressionMethods"
        ng-model="action.parameters.Method"
        default-value="'LZMA2'"></select>

এটি আমার পক্ষে কাজ করেছে, তবে কেবলমাত্র $scopeকলটি পেরিয়ে যাওয়ার পরে getter()- আশা করি এটির চেষ্টা করে অন্য কারও পক্ষে বিষয়টি পরিষ্কার হয়ে যায়!
জেসদা

0

@ মার্ক রাজককের পরামর্শ অনুযায়ী আমি চেষ্টা করেছিলাম। এটি স্ট্রিং মানগুলির জন্য কাজ করছে (ভিসা -২২৪২)। দয়া করে এই কোলাহলটি উল্লেখ করুন ।

মূর্খতা থেকে:

ফিডলে একই কাজটি ব্যবহার করে করা যেতে পারে ng-repeat, যা প্রত্যেকেই সুপারিশ করতে পারে। তবে @ মার্ক রাজককের দেওয়া উত্তরটি পড়ার পরে, আমি প্রোফাইলের অ্যারে সহ একটি ফর্মের জন্য একই চেষ্টা করতে চেয়েছিলাম। আমার কাছে $ স্কোপ.প্রোফাইলস = [{}, {}] থাকা পর্যন্ত জিনিসগুলি ভালভাবে কাজ করে; নিয়ামক কোড। যদি আমি এই কোডটি সরিয়ে ফেলি তবে আমি ত্রুটি পাচ্ছি। তবে সাধারণ পরিস্থিতিতে আমি $scope.profiles = [{},{}]; সার্ভার থেকে এইচটিএমএল প্রিন্ট করতে বা প্রতিধ্বনি হিসাবে মুদ্রণ করতে পারি না । <input name="card[description]" ng-model="card.description" ng-init="card.description='Visa-4242'">সার্ভার থেকে জাভাস্ক্রিপ্ট অংশটি প্রতিধ্বনিত না করে @ মার্ক রাজকোকের মতো স্ট্রিং মানগুলির জন্য যেমন অনুরূপ ফ্যাশনে উপরেরটি কার্যকর করা সম্ভব হবে ?


1
আপনি অ্যারের সূচনা করতে এনজি- টিআইআর
কারেন

0

রায়ান মন্টগোমেরি "ফিক্স" এ নির্বাচিত উপাদানগুলির জন্য সবেমাত্র সমর্থন যোগ করা হয়েছে

<select class="input-control" ng-model="regCompModel.numberOfEmployeeId" ng-initial>
    <option value="1af38656-a752-4a98-a827-004a0767a52d"> More than 500</option>
    <option value="233a2783-db42-4fdb-b191-0f97d2d9fd43"> Between 250 and 500</option>
    <option value="2bab0669-550c-4555-ae9f-1fdafdb872e5"> Between 100 and 250</option>
    <option value="d471e43b-196c-46e0-9b32-21e24e5469b4"> Between 50 and 100</option>
    <option value="ccdad63f-69be-449f-8b2c-25f844dd19c1"> Between 20 and 50</option>
    <option value="e00637a2-e3e8-4883-9e11-94e58af6e4b7" selected> Less then 20</option>
</select>

app.directive('ngInitial', function () {
return {
    restrict: 'A',
    controller: ['$scope', '$element', '$attrs', '$parse', function ($scope, $element, $attrs, $parse) {
        val = $attrs.sbInitial || $attrs.value || $element.val() || $element.text()
        getter = $parse($attrs.ngModel)
        setter = getter.assign
        setter($scope, val)
    }]
}

});


0

আপনার যদি ইউআরএলটিতে যেমন ডিগ্রি মান থাকে mypage/idতবে কৌনিক জেএস এর নিয়ামক হিসাবে আপনি location.pathnameআইডিটি সন্ধান করতে এবং এটি আপনার পছন্দমতো মডেলকে নির্ধারণ করতে পারেন।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.